1.AOP的切入点
连接点(Joint Point)指的是程序运行的某个阶段点,如某个方法的调用、异常抛出等。切入点(Pointcut)是连接点位置的集合,指明触发通知(Advice)的条件。Advice是某个连接点处的处理逻辑,也就是注入到连接点的代码。
2.Spring AOP切入点的3种实现
2.1 静态切入
静态切入点只限于给定的方法和目标类,而不考虑方法的参数。Spring在调用静态切入点时只在第一次调用的时候计算静态切入点的位置,然后缓存起来。通过org.springframework.aop.support.RegexpMethodPointcut可以实现静态切入点,是一个通用的正则表达式切入点。
<bean id="setPointcut" class="org.springframework.aop.support.RegexpMethodPointcut">
<property name="patterns">
<!--设定切入点-->
<list>
<value>.*save.*</value>
<value>.*do.*</value>
</list>
</property>
</bean>
.*save.*表示所有以save开头的方法都是切入点
2.2 动态切入点
动态切入点不仅限于给点的方法和类,动态切入点还可以指定方法的参数。因为参数具有变化性,所以动态切入点不能缓存。因此使用动态切入点对性能具有很大的损耗。
当切入点在执行时需要根据执行参数来调用Advice的时候,就需要使用动态切入点。Spring提供了内建的动态切入点:控制流切入点。此切入点匹配当前线程的调用堆栈。开发人员只有在当前线程执行时找到特定的类和特定的方法才能返回true。
大多数情况下都是使用静态切入点。
2.3 自定义切入点
因为Spring的切入点时JAVA类,所以可以自定义切入点。
3.Spring AOP的通知(Advice)
Spring提供了5中Advice类型:Interception Around、Before、After Returning、Thrown和Introductio。触发调用的情景为:在JointPoint前后、JointPoint前、JointPoint后、JointPoint抛出异常时、JointPoint调用完毕后。
3.1 Before通知
Before通知只在JointPoint前执行,实现Before通知的类需要实现接口MethodBeforeAdvice
public class XxxBeforeAdvice implements MethosBeforeAdvice {
public void before(Method m,Object[] args,Object target) throws Throwable{
//切入点处理逻辑
}
}
3.2 After Returning通知
Before通知只在JointPoint前执行,实现Before通知的类需要实现接口MethodAfterAdvice
public class XxxBeforeAdvice implements MethosAfterAdvice {
public void after(Method m,Object[] args,Object target) throws Throwable{
//切入点处理逻辑
}
}
3.3 Throw通知
Throw通知只在JointPoint抛出异常时执行,实现Throw通知的类需要实现接口ThrowAdvice
public class XxxBeforeAdvice implements ThrowAdvice{
public void afterThrowing(Method m,Object[] args,Object target) throws Throwable{
//切入点处理逻辑
}
}
3.4 Introduction通知
Introduction通知只在JointPoint调用完毕后执行,实现Introduction通知的类需要实现接口IntroductionAdvisor和接口IntroductionInterceptor
4.Spring的Advisor
Advisor是Pointcut和Advice的配置器,它是将Advice注入到程序中的Pointcut的代码。在Spring中主要通过XML配置的方式来配置Pointcut和Advice。
<bean id="exceptionHandlerAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="exceptionHandler"/>
</property>
<!-- 指定对任何方法都有效 -->
<property name="patterns">
<value>.*.*</value>
</property>
</bean>
5. Spring AOP的代理
5.1 Java自动代理
使用Java自动代理是,添加以下配置
<bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
然后配置上相应的Advisor即可。
5.2 CGLIB代理
5.2.1面向接口编程
添加如下配置,标记需要代理的接口、接口的实现类(target)和对应的Advisor。new对象时通过下面的此bean的id即可实现CGLIB代理
<bean id="logic1proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.test.aop.service.LogicInterface</value>
</property>
<property name="target">
<ref bean="logic1"/>
</property>
<property name="interceptorNames">
<list>
<value>timeHandlerAdvisor</value>
</list>
</property>
</bean>
5.2.2 面向类编程
添加如下配置,target中为需要代理的类,并配置上相应的Advisor即可。
<bean id="logic2proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyTargetClass">
<value>true</value>
</property>
<property name="target">
<ref bean="logic2"/>
</property>
<property name="interceptorNames">
<list>
<value>exceptionHandlerAdvisor</value>
</list>
</property>
</bean>