Spring中4中AOP区别
1. advisor类:需要依赖Spring接口,spring版本比较低时可以采取这种方式
2.<aop:advisor>:适合用户从低版本Spring迁移到高版本Spring,重复利用以前advice类情况
3.<aop:aspject>:使用配置文件形式定义切面,比较推荐的一种方式,使用于对维护性要求较高的情况
4.@aspject:使用注解形式定义切面,使用方便,但维护性比<aop:aspject>低
通Advisor类方式使用AOP
增强接口:MethodBeforeAdvice(前置增强)、AfterReturningAdvice(后置增强)、MethodInterceptor(环绕增强)、ThrowsAdvice(异常增强)、IntroductionInterceptor引介增强)
切点接口:StaticMethodMatcherPointcut(静态方法切点)、DynamicMethodMatcherPointcut(动态方法切点)(由于是在方法运行过程中决定切入条件,因此,很好性能)、ExpressionPointcut(表达式切点)、AnnotationMatcherPointcut(注解切点)、ControlFlowPointcut(控制流切点)、ComposablePointcut(复合切点)
切面:主要有三种类型,分别为简单切面(Advisor:有一个增强组成),切点切面(PointcutAdvisor:有一个切点和增强组成),引介切面(IntroductionAdvisor)
PointcutAdvisor实现类:
DefaultPointcutAdvisor:由一个切点对象和增强对象组成,使用范围最广的一种切面
NameMatcherMethodPointcutAdvisor:由NameMathcerMethodPointcut切点和增强组成,匹配指定字符方法名切点
RegexpMethodMatcherPointcutAdvisor:由RegexpMethodMatcherPointcut和增强组成,通过正则表达式匹配切点
AspjectJExpressionPointcutAdvisor:用于AspjectJ表达式定义切点的切面
AspjectPointcutAdvisor:用于AspectJ语法定义切面
通Advisor实现AOP例子如下
//切点对象
public class PointcutTest extends AbstractRegexpMethodPointcut{
.............
}
//增强
public class AdviceTest implement MethodBeforeAdvice{
.............
}
//业务类
public class service{
public void service1(){..}
public void service2(){....}
public void other(){....}
}
定义一个增强,及切点,再同增强和切点定义切面,最后通过ProxyFactoryBeaan工厂对目标类对象织入,ProxyFactoryBean有两个子类,分别代表使用CGLib和JDK方式产生代理对象,具体规则:如果代理生产接口则默认使用jdk方式,如果是类则使用CGLib方式。JDK和CGLib产生代理对象的优缺点,JDK产生代理对象性能比CGLib,但是代理对象使用性能CGLib比JDK高很多,因此,在使用单例模式可以使用CGLib方式产生代理,其他模式使用JDK产生代理比较好
每一个代理类都要配置代理工厂来代理,使用不够简化,Spring也意识到了这种问题,Spring提供自动产生代理工厂的创建类,主要有3种如下
基于Bean配置名规则的自动代理创建器:允许为一组特定配置名的Bean自动创建代理实例的代理创建器,实现类为BeanNameAutoProxyCreator
基于Advisor匹配机制自动代理创建器:它会扫描容器中所有的Bean,找出所有的Advisor对象,并自动将切面织入到目标对象中,实现类为DefaultAdvisorAutoProxyCreator
基于Aspject注解自动创建代理创建器:它会扫描容器中所有AspjectJ注解的类,并自动将切面织入到目标对象中,实现类为AnnotationAwareAspjectJAutoProxyCreator
上面的配置可以通过这种方式来简化配置
定义增强
<bean id="advice" class="AdviceTest" />
定义切点
<bean id="pointcut" class="PointcutTest" />
定义目标类
<bean id="serviceTarget" class="service" />
由切点和增强定义切面
<bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor" p
:advice-ref="advice" p:pointcut-ref="pointcut" />
使用自动代理创建器自动产生代理对象
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
基于<aop:advisor>实现织入
增强
<bean id="advice" class="AdviceTest" />
目标类
<bean id="service" class="<span style="font-family: Arial, Helvetica, sans-serif;">service</span><span style="font-family: Arial, Helvetica, sans-serif;">" /></span>
通aop定义切面
<aop:config>
<aop:advisor advice-ref="advice" pointcut="execution(* AdviceTest.service*(....))"/>
</aop:config>
使用advisor自动创建器
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
基于<aop:aspject>实现织入
public class AdviceTest1{
//增强函数,没依赖spring API
public void adviceMethod(){....}
}
配置文件:
增强
<bean id="advice" class="adviceTest1" />
<pre name="code" class="plain">目标类
<bean id="service" class="service"/>
使用注解创建器
<bean class="org.springframework.aop.framework.autoproxy.AnnotationAwareAspectJAutoProxyCreator" />
使用aop配置切面<aop:config> <aop:aspject ref="advice" > <aop:before pointcut="execution(* AdviceTest1.service*(...))" method="adviceMethod" /> </aop:aspject></aop:config>使用advisor自动创建器<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
//通过注解定义切面
@Aspject
public class AnnotationAdvisor{
@Before("execution(* service.service*(...))")
public void adviceMethod(){.....}
}
配置文件:
目标类
<bean id="service" class="service">
使用注解创建器
<bean class="org.springframework.aop.framework.autoproxy.AnnotationAspectJAutoProxyCreator" />
注意:在使用<Aop:advisor>、<aop:aspect>、@aspectJ时,可以用过JoinPoint对象获取目标类信息,引介增强使用ProceedingJoinPoint