Spring AOP:编程式
- MethodBeforeAdvice接口,前置增强接口spring
- MethodAfterReturningAdvice接口,后置增强接口spring
- MehodInterceptor 环绕增强接口,不是由spring提供的,是由AOP联盟开发的,spring只是借用他
Spring AOP:声明式
前置增强,后置增强,环绕增强
就是配置在xml中或者使用注解
SpringAop 抛出增强:程序报错,出现异常。
抛出异常需要实现ThrowsAdvice
SpringAOP引入增强:对方法的增强叫织入,对类的增强叫引入
继承DelegatingIntroductionInterceptor
<property name='proxyTargetClass' value='true'/>
它表明是否代理目标类,默认为false,也就是代理接口,此时Spring就用JDK动态代理;如果为true,那么Spring就用CGLIB动态代理。
切面:切面advisor封装了增强advice和切点Pointcut
切点:aop框架其实可以将它理解为一个拦截器框架,拦截匹配条件就是切点
配置一个切面:RegexpMethodPointcutAdvisor
advice增强:
pattern切点(正则表达式)
配置一个代理:
ProxyFactoryBean
target目标类:
interceptorNames切面
proxyTargetClass 代理目标类
Spring AOP:自动代理(扫描bean名称)
此时不能代理接口,只能代理类,因为不知道到底实现了多个个接口
BeanNameAutoProxyCreator
optimize:是否对代理生成策略进行优化,默认是false,如果是true,则可对代理生成策略进行优化。也就是说,该类有接口,就代理接口使用JDK代理,如果没有接口,就代理类。使用CGLib代理
CGLIb创建代理速度比较慢,但创建后运行的速度却非常快,而JDK动态代理正好相反。如果在运行时候不断的用CGLIB去创建代理,系统的性能会大打折扣,所以建议一般在系统初始化的时候用CGLIB去创建代理,并放入Spring的ApplicationContext中以后备用。
Spring AOP:自动代理(扫描切面配置)
Spring + AspectJ(基于注解:通过AspectJ execution表达式拦截方法)
@Aspect 注解表明该类是一个Aspect(其实就是Advisor)。该类无须实现任何的接口,只需定义一个方法,在方法上标注Around注解,在注解中使用AspectJ切点表达式。方法的参数中包括一个ProceedingJoinPoint对象,它在AOP中称为Joinpoint,可以通过该对象获取方法中的任何信息。例如方法名,参数等。
execution(* aop.demo.GreetingImpl.*(..))
解析:execution()表示拦截方法,括号中可定义需要匹配的规则
第一个*表示方法的返回值是任意的
第二个*表示匹配该类中所有方法
<aop:aspectj-autoproxy proxy-target-class='true'/>
proxy-target-class属性,默认值为false,只能代理接口(使用JDK代理),
当为true时,才能代表目标类(使用CGLib代理)
Spring + AspectJ(基于注解:通过AspectJ@annotation表达式拦截方法)
DeclareParents 引入增强 value目标类 defaultImpl 引入接口的默认实现类
增强类型 | 基于AOP接口 | 基于AOP注解 | 基于aop:config配置 |
---|---|---|---|
before advice | MethodBeforeAdvice | @Before | aop:before |
After advice | AfterReturningAdvice | @After | aop:after |
Around Advice | MethodInterceptor | @Around | aop:around |
Throws Advice | ThrowsAdvice | @AfterThrowing | aop:after-throwing |
Introduction Advice | DelegatingIntroductionInterceptor | @DeclareParents | aop:declare-parents |