AOP:不是由Spring定义.AOP联盟的组织定义.
AOP联盟为通知Advice定义了org.aopalliance.aop.Interface.Advice
Spring按照通知Advice在目标类方法的连接点位置,可以分为5类
前置通知 org.springframework.aop.MethodBeforeAdvice 在目标方法执行前实施增强
后置通知 org.springframework.aop.AfterReturningAdvice 在目标方法执行后实施增强
环绕通知 org.aopalliance.intercept.MethodInterceptor 在目标方法执行前后实施增强
异常抛出通知 org.springframework.aop.ThrowsAdvice 在方法抛出异常后实施增强
引介通知 org.springframework.aop.IntroductionInterceptor 在目标类中添加一些新的方法和属性(要求不大)
针对所有方法的增强:(不带有切点的切面)
第一步:导入相应jar包.
* spring-aop-3.2.0.RELEASE.jar
* com.springsource.org.aopalliance-1.0.0.jar
第二步:编写被代理对象:
* CustomerDao接口
* CustoemrDaoImpl实现类
第三步:编写增强的代码:
package cn.aop;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
/**
* 前置增强
* 要实现MethodBeforeAdvice接口
* 针对所有方法的增强:(不带有切点的切面)
* @author Administrator
*
*/
public class BeforeAdvice implements MethodBeforeAdvice{
/***
* method:执行的方法
* args:参数
* target:目标对象
*/
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
// TODO Auto-generated method stub
System.out.println("******前置增强");
}
}
第四步:生成代理:(配置生成代理:)
* 生成代理Spring基于ProxyFactoryBean类.底层自动选择使用JDK的动态代理还是CGLIB的代理.
* 属性:
target : 代理的目标对象
proxyInterfaces : 代理要实现的接口
如果多个接口可以使用以下格式赋值
<list>
<value></value>
....
</list>
proxyTargetClass : 是否对类代理而不是接口,设置为true时,使用CGLib代理
interceptorNames : 需要织入目标的Advice
singleton : 返回代理是否为单实例,默认为单例
optimize : 当设置为true时,强制使用CGLib
<!-- 不带有切点的切面 -->
<!--定义目标对象 -->
<bean id="customerDao" class="cn.aop.CustomerDaoImpl"></bean>
<!-- 定义增强 -->
<bean id="beforeadvice" class="cn.aop.BeforeAdvice"></bean>
<!-- spring的配置生成代理:ProxyFactoryBean是生成代理的类 -->
<bean id="customerDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 设置目标对象 -->
<property name="target" ref="customerDao"/>
<!-- 设置实现接口 ,value中写接口的全路径-->
<property name="proxyInterfaces" value="cn.aop.CustomerDao"/>
<!-- 要使用value;增强的id -->
<property name="interceptorNames" value="beforeadvice"/>
</bean>
带有切点的切面:(针对目标对象的某些方法进行增强)
PointcutAdvisor 接口:
DefaultPointcutAdvisor 最常用的切面类型,它可以通过任意Pointcut和Advice 组合定义切面
RegexpMethodPointcutAdvisor 构造正则表达式切点切面
第一步:创建被代理对象.
* OrderDao
第二步:编写增强的类:
package cn.aop2;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
* 增强的类(使用的是环绕增强)
* @author Administrator
*
*/
public class AroundAdvice implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("****环绕前增强");
Object result=methodInvocation.proceed();//执行目标对象的方法;proceed()表示放行
System.out.println("****环绕后增强");
return result;
}
}
第三步:生成代理:
<!-- 带有切点的切面 -->
<!--定义目标对象 -->
<bean id="orderDao" class="cn.aop2.OrderDao"></bean>
<!-- 定义增强 -->
<bean id="aroundAdvice" class="cn.aop2.AroundAdvice"></bean>
<!-- 定义切点切面:正则的 -->
<bean id="mypointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!-- 定义表达式,规定 哪些方法执行拦截-->
<!-- .任意字符,*任意个 。详细的写到那个包下的哪个类下方法(注意正则包名要进行转义)-->
<!--
<property name="pattern" value="cn\.aop2\.OrderDao\.find.*"/>
第二种如下:
-->
<!--
<property name="pattern" value=".*add.*"></property>
-->
<!-- 多个方法增强,改为patterns,并且多个用','隔开 -->
<property name="patterns" value=".*find.*,.*delete.*"></property>
<!-- 应用增强 -->
<property name="advice" ref="aroundAdvice"></property>
</bean>
<!-- 定义生成代理对象 -->
<bean id="orderDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 配置目标 -->
<property name="target" ref="orderDao"/>
<!-- 针对类的代理 -->
<property name="proxyTargetClass" value="true"/>
<!--在目标上 应用增强 -->
<property name="interceptorNames" value="mypointcutAdvisor"></property>
</bean>