spring aop
Aop面向切面编程
切面(Aspect):
一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关
注点的很好的例子。在Spring AOP中,切面可以使用基于模式)或者基于@Aspect注解的方式来实现。
连接点(Joinpoint):
在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。在Spring
AOP中,一个连接点总是表示一个方法的执行。
通知(Advice):
在切面的某个特定的连接点上执行的动作。其中包括了“around”、“before”和“after”等
不同类型的通知(通知的类型将在后面部分进行讨论)。许多AOP框架(包括Spring)都是以拦截器做通知模型,
并维护一个以连接点为中心的拦截器链。
切入点(Pointcut):
匹配连接点的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行
(例如,当执行某个特定名称的方法时)。切入点表达式如何和连接点匹配是AOP的核心:Spring缺省使用
AspectJ切入点语法。
引入(Introduction):
用来给一个类型声明额外的方法或属性(也被称为连接类型声明(inter-type
declaration))。Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象。例如,你可以使用引入
来使一个bean实现IsModified接口,以便简化缓存机制。
目标对象(Target Object):
被一个或者多个切面所通知的对象。也被称做被通知(advised)对象。 既然Spring
AOP是通过运行时代理实现的,这个对象永远是一个被代理(proxied)对象。
AOP代理(AOP Proxy):
AOP框架创建的对象,用来实现切面契约(例如通知方法执行等等)。在Spring中,
AOP代理可以是JDK动态代理或者CGLIB代理。
织入(Weaving):
把切面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。这些可以在编译时
(例如使用AspectJ编译器),类加载时和运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。
==================================================
==================================================
1.添加配置
<dependency> <groupId>aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.5.4</version> </dependency> <!-- 或者这个,他会自动导入aspectj, 用这个就可以使用annotation的注释功能--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>3.2.0.RELEASE</version> </dependency>
<?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" >
2.写一个通之类,用于添加到别处
public class MyAspect { public void beforeAdvice() { System.out.println("前置通知...."); } /*后置通知如果需要接受方法的返回值才能做下去的话,参数是OBj,因为不知道返回式 是什么类型*/ public void afterAdvice(Object obj) { System.out.println("后置通知..." + obj); } // 如果需要获取异常信息,可以传入参数信息 public void exceptionAdvice(Exception ex) { System.out.println("异常通知..." + ex.getMessage()); } public void finallyAdvice() { System.out.println("最终通知...."); } //需要传进去参数ProceedingJoinPoint public void aroundAdvice(ProceedingJoinPoint jp) { try { System.out.println("前置通知"); // 这个方法代表了目标方法的执行 Object obj = jp.proceed(); System.out.println("后置通知"); } catch (Throwable e) { e.printStackTrace(); System.out.println("异常通知"); } finally { System.out.println("最终通知"); } } }
3.将写通知的类交给spring管理
<!-- 1.将通知类交给Spring管理 --> <bean id="myAspect" class="com.kaishengit.service.MyAspect"/> <!-- 配置aop项 --> <aop:config> <!-- ref定义通知类是哪一个 --> <aop:aspect ref="myAspect"> <!-- 2.定义切入点表达式 :指的是指定通知类加载到哪个类,哪个方法上 第一个*代表方法的返回类型(各种) com.kaishengit.dao包名 ..(两个)指的是本包,及其子包 *代表这个包里面的所有类 .后面的*,代表类里面的所有方法 (..)参数列表不限--> <aop:pointcut expression="execution(* com.kaishengit.dao..*.*(..))" id="myPointcut"/> <!-- 3.定义通知类型 --> <!-- 前置通知 method="beforeAdvice"指定前置通知的方法,指定切入点表达式--> <aop:before method="beforeAdvice" pointcut-ref="myPointcut"/> <!-- 后置通知 ,有返回值的话,就把返回值给后置通知.return的是OBJ,因为返回的类型不定--> <aop:after-returning method="afterAdvice" pointcut-ref="myPointcut" returning="obj"/> <!-- 异常通知 如果需要知道异常信息 throwing="ex"--> <aop:after-throwing method="exceptionAdvice" pointcut-ref="myPointcut" throwing="ex"/> <!-- 最终通知 --> <aop:after method="finallyAdvice" pointcut-ref="myPointcut"/> <!-- 这是环绕通知,与前面的四个有可替代性,定义了前面四个,就不要定义这个 定义这个,就不要定义前面四个,他可以替代前面的四个通知,方法在上面定义,上去看看--> <aop:around method="aroundAdvice" pointcut-ref="myPointcut"/> </aop:aspect> </aop:config>