- 浏览: 407057 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (158)
- SpringBoot (10)
- vue.js (4)
- 2017基础知识 (2)
- jquery (4)
- extjs (8)
- spring (13)
- Java基础 (24)
- ibatis (2)
- oracle (18)
- 服务器配置 (8)
- maven (7)
- web应用开发 (14)
- 数据库 (9)
- 第三方依赖 (3)
- 百味人生 (7)
- svn (1)
- 问题一堆 (2)
- 测试驱动开发 (1)
- webServices (2)
- 网络编程 (2)
- 其它 (4)
- hibernate (2)
- ec标签序号列 (1)
- javascript (1)
- ActiveMQ (2)
- linux (5)
- UI (1)
- 问题汇集 (1)
- redis (1)
最新评论
-
jackson200:
讲解的狠不错!谢谢!
spring注入原理 -
阳光泛滥的日子:
讲的很透彻,受教了 。
spring中注解的实现原理 -
liudechao9:
最近在研究这方面,很不错,但是多线程并发的时候可能会出问题,而 ...
spring中注解的实现原理 -
小帅1127:
厉害啊 我的哥
spring中注解的实现原理 -
phoenixpaul:
...
Oracle存储过程和程序包
一、AOP是Aspect Oriented Programing 的简称,面向方面(切面)编程。
(1)、AOP的应用场合:适用于那些具有横切逻辑的应用场合,如:性能检测、访问控制、事务管理以及日志记录。
(2)、面向切面编程的概念:假设我们将ForumService业务类看成一段圆木,将removeTopic()方法和createForum()方法看成圆木的一截,我们会发现性能检测和事务管理的代码就好像一个年轮,而业务代码就是圆木的树心,这也正是横切代码概念的又来。而AOP希望将这些分散的各个业务逻辑代码中的相同代码,通过横向切割的方式抽取到一个独立的模块中,
还业务逻辑一个清新的世界。当让,我们知道将这些重复的横切逻辑独立出来很容易,但如何将这些独立的逻辑融合到业务逻辑中完成和原来一样的业务操作,这才是事情的关键,也正式AOP要解决的主要问题。
(3)、AOP术语
1、连接点(joinPoint)和切点(pointCut):每个程序类都拥有多个连接点,如一个拥有两个方法的类,这两个方法都是连接点,即连接点是程序类中客观存在的事务。但在这为数众多的连接点中,如何定位到敢兴趣的连接点呢?AOP通过"切点(pointCut)"定位特定连接点。通过数据库查询的概念来理解切点和连接点的关系再合适不过了;连接点相当于数据库中的记录,而切点相当于查询条件。切点和连接点不是一对一的关系,一个切点可以匹配多个连接点。
2、增强(Advince):是织入到目标类连接点上的一段程序代码。
3、目标对象(Target):增强逻辑织入的目标类。
4、织入(weaving):织入是将增强添加对目标类具体连接点的过程。AOP就想一台织布机,将目标类、增强或者引介通过AOP这台织布机天衣无缝的编织在一起。
根据不同的织入技术,AOP有三种织入方式:
1)、编译期织入,这要求使用特殊的Java编译器。
2)、类装载期织入,这要求使用特殊的类装载器。
3)、动态代理织入,在运行期为目标类添加增强生成子类的方式。
5、代理(Proxy):一个类被AOP织入增强以后,就产生了一个结果类,它是融合了源类和增强逻辑的代理类。根据不同的代理方式,代理类既可能是和原类具有相同
接口的类,也可能是原来类的子类,所以我们可以采用调用原来类相同的方式调用代理类。
6、切面(Aspect):切面是由切点和增强(引介)组成的,它既包含了横切逻辑的定义,也包括了连接点的定义,SpringAOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中。
(4)、AOP的工作重心:如何将增强应用于目标连接点上,这是首先包括两个工作:第一,如何通过切点和增强定位到连接点上;第二:如何在增强中编写切面的代码。
(5)、AOP的实现原理:Spring AOP使用动态代理技术在运行期间织入增强的代码,Spring AOP使用两种代理机制;一种是基于Jdk的动态代理;另一种是基于CGlib的动态代理,很大程度上JDK本身只提供接口的代理,而不支持类的代理。
二、简单的示例:
package com.yt.spring.user; /** * @Description:定义接口类 * @ClassName: IUserBean * @Project: spring-aop * @Author: zxf * @Date: 2011-5-23 */ public interface IUserBean { public UserBean getUser(String userId); public int deleteUser(String userId); public void insertUser(UserBean user); }
package com.yt.spring.user; import org.apache.log4j.Logger; /** * @Description: 实现类 * @ClassName: UserBeanImpl * @Project: spring-aop * @Author: zxf * @Date: 2011-5-23 */ public class UserBeanImpl implements IUserBean { Logger log = Logger.getLogger(UserBeanImpl.class); @Override public UserBean getUser(String userId) { log.info("查找用户.............."); return null; } @Override public int deleteUser(String userId) { log.info("删除用户.............." + userId); return 100; } @Override public void insertUser(UserBean user) { log.info("添加用户.............."); } }
package com.yt.spring.user; /** * @Description: 实体类 * @ClassName: UserBean * @Project: spring-aop * @Author: zxf * @Date: 2011-5-23 */ public class UserBean { public String userId; public String userName; public String userAddress; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserAddress() { return userAddress; } public void setUserAddress(String userAddress) { this.userAddress = userAddress; } }
(1)、使用注解的方式来声明代理类
package com.yt.spring; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; /** * @Description: 使用注解的方式来声明切面类 * @ClassName: MyInterceptor * @Project: spring-aop * @Author: zxf * @Date: 2011-5-23 */ @Aspect public class MyInterceptor { /** * 定义切入点 * 第一个*表示方法的返回值,这里使用通配符,只有返回值符合条件的才拦截,(!void表示有返回值) * 第一个..表示com.royzhou.aop包及其子包 * 倒数第二个*表示包下的所有Java类都被拦截 * 最后一个*表示类的所有方法都被拦截 * (..)表示方法的参数可以任意多个如[(java.lang.String,java.lang.Integer)表示第一个参数是String, * 第二个参数是int的方法才会被拦截] */ @SuppressWarnings("unused") @Pointcut("execution(* com.yt.spring.user.*.*(..))") private void pointCutMethod() { } // 定义置前通知 @Before("pointCutMethod()&&args(userId)") public void doBefore(String userId) { System.out.println("定义前置通知.........方法获取参数:" + userId); } // 定义后置通知 @AfterReturning(pointcut = "pointCutMethod()", returning = "result") public void doAfterReturning(int result) { System.out.println("定义置后通知.........方法返回值:" + result); } // 定义例外通知 @AfterThrowing(pointcut = "pointCutMethod()", throwing = "e") public void doAfterException(String e) { System.out.println("定义例外通知.........出现异常:" + e); } // 定义最终通知 @After("pointCutMethod()") public void doAfter() { System.out.println("定义最终通知........."); } // 定义环绕通知 @Around("pointCutMethod()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { System.out.println("进入方法"); Object object = pjp.proceed(); // 必须执行pjp.proceed()方法,如果不执行此方法,业务bean的方法以及后续通知都不执行 System.out.println("退出方法"); return object; } }
对应的applicationContext.xml配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:ehcache="http://www.springmodules.org/schema/ehcache" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd"> <!-- 打开aspectj注解处理器,proxy-target-class="true"表示使用CGlib实现类代理--> <aop:aspectj-autoproxy proxy-target-class="true"/> <!-- 配置切面bean --> <bean id="MyInterceptor" class="com.yt.spring.MyInterceptor"></bean> <bean id="userBean" class="com.yt.spring.user.UserBeanImpl"></bean> </beans>
(二)、使用配置的方式来声明切面类
package com.yt.spring; import org.aspectj.lang.ProceedingJoinPoint; /** * @Description: 使用xml配置的方式来声明切面类 * @ClassName: MyInterceptor * @Project: spring-aop * @Author: zxf * @Date: 2011-5-23 */ public class MyInterceptorXml { // 定义置前通知 public void doBefore(String userId) { System.out.println("定义前置通知.........方法获取参数:" + userId); } // 定义后置通知 public void doAfterReturning(int result) { System.out.println("定义置后通知.........方法返回值:" + result); } // 定义例外通知 public void doAfterException(String e) { System.out.println("定义例外通知.........出现异常:" + e); } // 定义最终通知 public void doAfter() { System.out.println("定义最终通知........."); } // 定义环绕通知 public Object doAround(ProceedingJoinPoint pjp) throws Throwable { System.out.println("进入方法"); Object object = pjp.proceed(); // 必须执行pjp.proceed()方法,如果不执行此方法,业务bean的方法以及后续通知都不执行 System.out.println("退出方法"); return object; } }
applicationContext.xml对应的配置:
<bean id="MyInterceptorXml" class="com.yt.spring.MyInterceptorXml"></bean> <aop:config> <aop:aspect id="asp" ref="MyInterceptorXml"> <aop:pointcut id="mycut" expression="execution(* com.yt.spring.user.*.*(..))"/> <aop:before pointcut="execution(* com.yt.spring.user.*.*(..)) and args(userId)" method="doBefore"/> <aop:after-returning pointcut-ref="mycut" method="doAfterReturning" returning="result"/> <aop:after-throwing pointcut-ref="mycut" method="doAfterException" throwing="e"/> <aop:after pointcut-ref="mycut" method="doAfter"/> <aop:around pointcut-ref="mycut" method="doAround"/> </aop:aspect> </aop:config>
最后贴出测试类:
package com.yt.spring; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.yt.spring.user.IUserBean; /** * @Description:测试AOP * @ClassName: Test * @Project: spring-aop * @Author: zxf * @Date: 2011-5-23 */ public class Test { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext( "applicationContext.xml"); // 接口代理 IUserBean userBean = (IUserBean) ctx.getBean("userBean"); // UserBeanImpl userBean = (UserBeanImpl) ctx.getBean("userBean"); userBean.deleteUser("419688091"); } }
发表评论
-
SpringMVC @ResponseBody和@RequestBody使用
2018-02-08 09:54 849@ResponseBody用法 作用: 该注解用 ... -
http请求中的header和body应用
2016-11-12 16:42 12615/** * 获取httpBody中的请求数据处理后并 ... -
spring中注解的实现原理
2011-06-07 16:50 36513@Autowired和@Resource的区别 ... -
spring管理bean原理
2011-06-03 15:24 19681、读取config.xml文件的bean标签放入数组,读取内 ... -
spring注入原理
2011-05-19 14:05 20235IOC(Inverse of Control)可翻 ... -
spring+ibatis
2011-05-06 17:10 1334applicationContext.xml <!-- ... -
springMVC上传文件
2011-01-18 10:52 1574(1)、加入jar包: jxl-2.6.jar com ... -
spring 的工作机制和配置文件
2010-12-06 11:17 1069spring工作机制及为什么 ... -
spring中的事务管理
2010-11-04 14:35 11231、spring中声明式事务有两种配置方法:注解配置和xml形 ... -
Spring Web 相关工具类
2010-11-03 17:16 1032Web 相关工具类 您几乎总是使用 Spring ... -
spring 中的jdbc
2010-11-02 09:17 1709package org.spring.service; ... -
extjs3+springMVC上传文件
2010-04-02 09:46 67301.Ext代码 //formPanel表单的属性加入 fi ...
相关推荐
spring AOP 基础 教程文档。 spring AOP 基础 教程文档。
关于AOP是什么的理解,对有java编程基础的初学者者来说绝对有用
声明规则属性设置(来源于 Spring AOP Schema 类型 basicAdviceType)pointcut: Pointcut 表达式内容pointc
3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑...
spring aop hessian 基础demo 部署即可运行
Spring基础:Spring AOP简单使用
spring基础Spring IOC和Spring AOP的原理及使用
课程内容非常详细的介绍Spring AOP全栈技术点,开篇帮助同学们进行知识储备,夯实基础就是核心!课程从Spring AOP概念开始引入,通过Spring AOP代理和判断模式进行,宝库各种模式,不断的深入学习,相信会给同学们...
* * * * Core Container(核心容器) Spring的核心容器是其他模块建立的基础,它主要由Beans模块、Core模块、Context模块、Context-support模块和SpEL(Spring Expression Language,Spring表达式语言)模块组成,...
spring AOP 的简单使用. 博文链接:https://dd350356750.iteye.com/blog/232955
动态代理是实现AOP的基础,它通过JDK动态代理或CGLIB代理生成被代理对象的子类。通知是织入到目标对象连接点上的一段程序,例如@Before、@After等。 切点定义了通知应该在哪些连接点上触发。而切面则是通知和切点的...
SPRING AOP自主实现,还包括一些java基础,可以很快自主实现切面编程
com.springsource.net.sf.cglib-2.2.0.jar,com.springsource.org.aopalliance-1.0.0.jar,com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar,还有个基础包就不说了
非常详细的介绍Spring AOP全栈技术点,开篇帮助同学们进行知识储备,夯实基础就是核心!从Spring AOP概念开始引入,通过Spring AOP代理和判断模式进行,宝库各种模式,不断的深入学习,相信会给同学们带来不一样的...
1,spring是一个开源的免费的框架(容器)。 2,spring是一个轻量级的,非入侵式的框架。 非入侵式:就是项目引入了这个框架之后,...总结:spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架。
包含学习 Spring AOP还所需的基础jar包,需要的朋友可以下载哈!
spring-**cntext**-4.3.6.RELEASE.jar:spring提供了基础IOC功能上的扩展服务,提供了很多企业级服务的支持,如邮件服务,任务调度,JNDI定位,EJB集成,远程访问,缓存以及各种试图层框架的封装等。 spring-...
基础spring全套Jar包加上AOP习所需的三个jar包,基本满足spring的基础使用开发
记录基础
在Spring1.2或之前的版本中,实现AOP的传统方式就是通过实现Spring的AOP API来定义Advice,并设置代理对象。Spring根据Adivce加入到业务流程的时机的不同,提供了四种不同的Advice:Before Advice、After Advice、...