针对类实现代理,对是否实现接口无要求。原理是对指定的类生成一个子类,覆盖其中的方法,因为是继承,所以被代理的类或方法最好不要声明为final类型。 1. 定义一个实现了MethodInterceptor接口的类 2. 实现其intercept()方法,在其中调用proxy.invokeSuper( )
Joinpoint(连接点): 类里面可以被增强的方法,这些方法称为连接点 Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义. Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能) Aspect(切面): 是切入点和通知(引介)的结合 Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field. Target(目标对象):代理的目标对象(要增强的类) Weaving(织入):是把增强应用到目标的过程,把advice 应用到 target的过程 Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类 其实我们只需要这么记忆即可:
切入点:在类里边可以有很多方法被增强,比如实际操作中,只是增强了个别方法,则定义实际被增强的某个方法为切入点。
通知/增强:增强的逻辑,称为增强,比如扩展日志功能,这个日志功能称为增强。包括:
前置通知:在方法之前执行
后置通知:在方法之后执行
异常通知:方法出现异常执行
最终通知:在后置之后执行
环绕通知:在方法之前和之后执行
切面:把增强应用到具体方法上面的过程称为切面。
[html] view plain copy <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
常用的表达式 execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>) (1)execution(* cn.itcast.aop.Book.add(..)) (2)execution(* cn.itcast.aop.Book.*(..)) (3)execution(* *.*(..)) (4) 匹配所有save开头的方法 execution(* save*(..))
1、首先定义一个Book类,里边有方法add(),也就是切入点(被增强的方法)
[java] view plain copy package cn.ywq.aop; public class Book { public void add() { System.out.println("add..........."); } }
2、定义一个MyBook类,里边有可以用来增强的方法,即某些功能方法代码。我们要实现的就是将某些功能方法加入切入点。
[java] view plain copy package cn.ywq.aop; import org.aspectj.lang.ProceedingJoinPoint; public class MyBook { public void before1() { System.out.println("前置增强......"); } public void after1() { System.out.println("后置增强......"); } //环绕通知 public void around1(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { //方法之前 System.out.println("方法之前....."); //执行被增强的方法 proceedingJoinPoint.proceed(); //方法之后 System.out.println("方法之后....."); } } 3、核心配置文件:
[html] view plain copy <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 1 配置对象 --> <bean id="book" class="cn.ywq.aop.Book"></bean> <bean id="myBook" class="cn.ywq.aop.MyBook"></bean> <!-- 2 配置aop操作 --> <aop:config> <!-- 2.1 配置切入点 --> <aop:pointcut expression="execution(* cn.ywq.aop.Book.*(..))" id="pointcut1"/> <!-- 2.2 配置切面 把增强用到方法上面 --> <aop:aspect ref="myBook"> <!-- 配置增强类型 method: 增强类里面使用哪个方法作为前置 --> <aop:before method="before1" pointcut-ref="pointcut1"/> <aop:after-returning method="after1" pointcut-ref="pointcut1"/> <aop:around method="around1" pointcut-ref="pointcut1"/> </aop:aspect> </aop:config> </beans>
4、测试类如下:
[java] view plain copy package cn.ywq.aop; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestAnno { @Test public void testService() { ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml"); Book book = (Book) context.getBean("book"); book.add(); } } 5、结果如下:
以上就是我们使用aop的一个基本简单介绍,这样我们便可以在业务逻辑代码前后加一些功能性代码了,比如日志记录,性能统计,安全控制,事务处理,异常处理。