Spring--Aop-AspectJ

AspectJ:
AspectJ是一个基于Java语言的AOP框架

jar包:
 AOP联盟:com.springsource.org.aopalliance-1.0.0.jar
 spring aop实现:spring-aop-3.2.0.RELEASE.jar
 Aspectj规范:com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
 spring aspect实现:spring-aspects-3.2.0.RELEASE.jar

 切入点表达式:
1.execution()  用于描述方法(用法在spring--aop中有介绍)
2.within() 用于描述包的,匹配包或子包中的方法(了解)
3.this() 用于描述当前对象,匹配实现接口的代理对象中的方法(了解)
4.target() 用于描述目标对象,匹配实现接口的目标类中的方法(了解)
5.args() 用于描述参数,匹配参数格式符合标准的方法(了解)
6.bean() 用于描述指定bean

通知类型:
aspectj通知类型:前置通知、后置通知、环绕通知、异常抛出通知、最终通知
1)before:前置通知(应用:各种校验)
 在方法执行前执行,如果通知抛出异常,阻止目标方法运行
2)afterReturning:后置通知(应用:常规数据处理)
 方法正常返回后执行,如果目标方法中抛出异常,通知无法执行
 必须在方法执行后才执行,所以可以获得方法的返回值。
3)around:环绕通知(应用:十分强大,可以做任何事情)【必须是Object的,必须要有第一个参数,
它的参数是JoinPoint的子接口ProceedingJoinPoint joinPoint,对外必须要抛出异常,
手动执行目标方法joinPoint.proceed()】
 方法执行前后分别执行,可以阻止方法的执行
4)afterThrowing:抛出异常通知(应用:包装异常信息、记录日志(info、warn、error)等)
 方法抛出异常后执行,如果方法没有抛出异常,无法执行
5)after:最终通知(应用:清理现场)
 方法执行完毕后执行,无论方法中是否出现异常
环绕
try{
   //前置通知
   手动执行目标方法 Object obj = ...
   //后置通知
} catch{
   //抛出异常通知
} finally{
   //最终通知
}

通知演示XML配置:
public class MyAspect {
 
 public void myBefore(JoinPoint joinPoint){
  System.out.println("前置通知:" + joinPoint.getSignature().getName());
 }
 public void myAfterReturning(JoinPoint joinPoint,Object val){
  System.out.println("后置通知:" + joinPoint.getSignature().getName() + " @ " + val);
 }
 
 public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
  System.out.println("环绕前");
  //手动执行目标方法
  Object obj = joinPoint.proceed();
  
  System.out.println("环绕后");
  return obj;
 }
 
 public void myAfterThrowing(JoinPoint joinPoint, Throwable e){
  System.out.println("抛出异常通知" + e.getMessage());
 }
 
 public void myAfter(JoinPoint joinPoint){
  System.out.println("最终通知");
 }
}
<!-- 1 创建service -->
 <bean id="userServiceId" class="cn.xxx.d_aspect.a_xml.UserServiceImpl"></bean>
 <!-- 2 切面类 -->
 <bean id="myAspectId" class="cn.xxx.d_aspect.a_xml.MyAspect"></bean>
 <!-- 3 aop aspectj编程
  <aop:aspect> 进行aspect配置,切面配置
   * ref 用于引用切面类,从而确定通知(方法名)
  <aop:pointcut> 声明切入点
 -->
 <aop:config>
  <aop:aspect ref="myAspectId">
   <aop:pointcut expression="execution(* cn.xxx.d_aspect.a_xml.*.*(..))" id="myPointcut"/>
   <!-- 3.1 前置通知
    * 配置:<aop:before method="myBefore" pointcut-ref="myPointcut"/>
    * 通知:public void myBefore(JoinPoint joinPoint){
     具有一个参数,可以获得当前连接点的描述信息。例如:方法名称 joinPoint.getSignature().getName()
     类型:org.aspectj.lang.JoinPoint
   <aop:before method="myBefore" pointcut-ref="myPointcut"/>
   -->
   <!-- 3.2 后置通知 ,在目标方法之后执行,所以可以获得目标方法返回值
    * 配置:<aop:after-returning method="myAfterReturning" pointcut-ref="myPointcut" returning="val"/>
    * 通知:public void myAfterReturning(JoinPoint joinPoint,Object val){
     参数1:当前连接点描述
     参数2:返回值,类型必须是Object,参数名称必须是 <aop:after-returning ...returning="
">设置的。
   <aop:after-returning method="myAfterReturning" pointcut-ref="myPointcut" returning="val"/>
   -->
   <!-- 3.3 环绕通知 ,必须手动执行目标方法
    * 配置:<aop:around method="myAround" pointcut-ref="myPointcut" />
    * 通知:public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
     1)返回类型必须是Object
     2)方法参数必须是ProceedingJoinPoint
     3)必须抛出异常Throwable
     4)执行目标方法:Object obj = joinPoint.proceed();
   <aop:around method="myAround" pointcut-ref="myPointcut" />
   -->
   <!-- 3.4 抛出异常 ,只有发生异常时,才执行。通常不执行。
    * 配置:<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointcut" throwing="e"/>
    * 通知:public void myAfterThrowing(JoinPoint joinPoint, Throwable e){
     参数1:。。。
     参数2:异常的描述信息,类型必须Throwable,参数名称通过 throwing 配置确定
   <aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointcut" throwing="e"/>
   -->
   <!-- 3.5 最终通知
    * 配置: <aop:after method="myAfter" pointcut-ref="myPointcut"/>
    * 通知:public void myAfter(JoinPoint joinPoint){
   -->
   <aop:after method="myAfter" pointcut-ref="myPointcut"/>
  </aop:aspect>
 </aop:config>

注解配置:
@service声明service层,加注在service的实现层上@service("userService")。
@Component声明不好归类的组件。例如:@Component("myAspectId")
service和component的生效要通过context的扫描才能够生效。

@Aspect 声明切面 @Before 前置 @AfterReturning 后置 @Around 环绕
@AfterThrowing 抛出异常 @After  最终
@Pointcut  声明切入点,修饰固定方法上  private void 自定义(){}
以上注解要生效,必须在xml配置
<aop:aspectj-autoproxy>

前置通知:@Before("execution(* cn.xxx.d_aspect.b_annotation.*.*(..))")
后置通知:@AfterReturning(value="myPointCut()" ,returning="val")
   声明切入点,达到表示共享。使用时相当于方法调用
    @Pointcut("execution(* cn.xxx.d_aspect.b_annotation.*.*(..))")
    private void myPointCut(){}【在切面类中进行声明】

环绕通知:@Around("execution(* cn.xxx.d_aspect.b_annotation.*.*(..))")
抛出异常通知:@AfterThrowing(value="myPointCut()" ,throwing="e")


 

猜你喜欢

转载自jackpot1234.iteye.com/blog/2310369