AOP开发的概念
1,JoinPoint(连接点):所谓连接点是指那些被拦截的点,而spring中这些点就是指方法,因为spring只支持方法类型的连接点。
2,PointCut(切入点):所谓切入点就是指我们要对那些JoinPoint进行拦截的定义。
3,Advice(通知/增强):所谓通知/增强,就是指拦截到JoinPoint后需要完成的事情。他分为前置通知/增强,后置通知/增强,异常通知/增强,最终通知/增强,环绕
通知/增强(切面要完成的功能);
4,Introduction(引介):引介是一种特殊的Advice,在不修改代码的前提下,引介可以在运行期为类动态的添加一些方法或Field。
5,Target(目标):代理对象的目标对象(要增强的类)
6,Weaving(织入):把Advice应用到Target的过程
7,Proxy(代理):一个类被AOP注入增强后,就产生了一个结果代理类
8,Aspect(切面):是PointCut和Advice(Introduction)的结合
编写目标类Man.java
public class Man{
public void eat() {
System.out.println("喝酒");
}
}
1. 前置通知:
前置通知,即能够实现在目标类执行之前增加一些方法
前置通知需实现MethodBeforeAdvice接口,并实现它的before方法,在这个方法中可以定义需要在目标类执行之前的添加的功能;
public class MyBeforeAdvice implements MethodBeforeAdvice{
@Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println("抽烟");
}
}
当然,在定义了前置通知的类的后,为了能时目标类执行之前执行添加的功能,应该要搭建一个桥梁,连接这两个类;所以需要在配置文件中搭建这个这个桥梁。
首先,在applicationContext.xml文件中声明目标类对象以及前置增强类对象,然后搭建这两个对象之间的强梁;
<bean id="man" class="com.sxt.bean.Man"></bean>
<bean id="myBeforeAdvice" class="com.sxt.bean.MyBeforeAdvice"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.sxt.bean.Man.*())" id="pc"/>
<!--advice-ref的值是前置增强对象的id,pointcut-ref的值是aop:pointcut标签的ID-->
<aop:advisor advice-ref="myBeforeAdvice" pointcut-ref="pc"/>
</aop:config>
2. 后置通知
与前置通知的意义是一样的,只不过后置增强是在目标类执行之后添加的功能;
后置通知需要实现AfterReturningAdvice接口,并且实现他的afterReturning类
public class MyAfterAdvice implements AfterReturningAdvice{
@Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
System.out.println("烫头");
}
}
定义了后置通知的类后也需要与目标类搭建桥梁,首先,在applicationContext.xml文件中声明目标类对象以及后置通知类对象,然后搭建这两个对象之间的强梁;
<bean id="man" class="com.sxt.bean.Man"></bean>
<bean id="myAfterAdvice" class="com.sxt.bean.MyAfterAdvice"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.sxt.bean.Man.*())" id="pc"/>
<aop:advisor advice-ref="myBeforeAdvice" pointcut-ref="pc"/>
<aop:advisor advice-ref="myAfterAdvice" pointcut-ref="pc"/>
</aop:config>
3. 环绕通知
环绕通知可以视为前置通知和后置通知的叠加,其效果是一样的
环绕通知类需要实现MethodInterceptor接口,并且实现它的invoke方法;
注意:此处的MethodInterceptor接口是org.aopalliance.intercept包下的
public class MyArroundAdvice implements MethodInterceptor{
/*
* arg0.proceed();的作用是执行目标对象的方法
*/
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
System.out.println("抽烟");
arg0.proceed();
System.out.println("烫头");
return null;
}
}
环绕通知在applicationContext.xml文件中的配置如下
<bean id="man" class="com.sxt.bean.Man"></bean>
<bean id="myArroundAdvice" class="com.sxt.bean.MyArroundAdvice"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.sxt.bean.Man.*())" id="pc"/>
<aop:advisor advice-ref="myArroundAdvice" pointcut-ref="pc"/>
</aop:config>
4. 异常通知
异常通知是在目标对象执行过程中发生了异常后,需要添加的功能;
先定义一个异常通知类,这个类需要实现ThrowsAdvice接口,这个接口是空的,没有需要实现的方法。为了 添加需要的功能,需要在这个类中写一个方法。但是,这里需要注意,虽然没有实现方法,可以写一个方法,但是这个方法的名称必须为afterThrowing,并且需要接受一个Throwable对象,否则就会报错
public class MyExceptionAdvice implements ThrowsAdvice{
public void afterThrowing(Throwable tw) throws Throwable {
System.out.println("====发生了异常======");
}
}
异常通知在applicationContext.xml文件中的配置如下
<bean id="man" class="com.sxt.bean.Man"></bean>
<bean id="myExceptionAdvice" class="com.sxt.bean.MyExceptionAdvice"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.sxt.bean.Man.*())" id="pc"/>
<aop:advisor advice-ref="myExceptionAdvice" pointcut-ref="pc"/>
</aop:config>
总结:
由以上的各段代码可以的到一个规律,普通AOP开发的配置文件的方法,不同的通知,其配置的形式都是一样的;
每一个通知类都是实现了一个接口,并且实现了它的一个方法,在这个方法中定义功能;但异常通知是一个意外,它所实现的接口并没有需要实现的方法,所以这个方法需要自己写。