Spring4基础 学习笔记(4) ---- AOP(2) ---- AspectJ基于注解

AspectJ:实现AOP的框架,Spring引入了它
 
AspectJ中常用的五種類型:
前置通知
後置通知
環繞通知
異常通知
最終通知:相當於try-catch中的finally
 
AspectJ的切入點表達式:加方括號表示可以省略,各部分用空格隔開
execution ( [ modifiers-pattern ]     訪問權限類型
ret-type-pattern 返回值類型
[declaring-type-pattern ] 全限定性類名
name-pattern(param-oattern)  方法名(參數名)
[throws-pattern] 拋出異常類型     )
 
在其中可以使用以下符號
符號 意義
* 0至多個任意字符
.. 用在方法參數中,表示任意多個參數;用在包名之後,表示當前包及其子包路徑
+
用在類名后,表示當前類及其子類
用在接口后,表示當前接口及其實現類
 
 
舉例:
execution(public**(..)) :public訪問權限  ,   *返回值任意 , *方法名任意  ,  ---->表示任public方法
execution(*set*(..)) : 任何一個以set開始的方法
 
execution(* *.service.*.*(..)) : 只有一級包下的service所有類(接口)中所有方法為切入點  com.service.myservice.doFirst()可以匹配  com.package.myservice.doFirst不能匹配
execution(* *..service.*.*(..)) : 表示service前面可以有多級包
 
 
AspectJ的开发环境 : 
AspectJ jar
Spring整合AspectJ
 
引入AOP约束
 
AspectJ基于注解的AOP实现:
1)前置通知:
//表示当前类为切面
@Aspect
public class MyAspect {
      
      //前置通知,AspectJ表达式
      @Before("execution(* ISomeService.doFirst(..))")
      public void before() {
            System.out.println("前置通知方法");
      }
     @Before
public void  before1(JoinPoint jp) {               //jp表示执行过程中具体的切入点表达式
            System.out.println("前置通知方法");
 }
}
 
<bean id="someService" class="ISomeServiceImpl" />
 
<!-- 注册切面 -->
<bean id="myAspect" class="MyAspect"/>
      
<!-- AspectJ的自动代理 -->
<aop:aspectj-autoproxy/>
 
2)后置通知:
      //后置通知
      @AfterReturning("execution(* ISomeService.doSecond(..))")
      public void After() {
            System.out.println("后置通知");
      }
     
     //取得返回值
@AfterReturning(value="execution(* ISomeService.doSecond(..))", returning="result")
      public void AfterReturning(String result) {
            System.out.println("后置通知");
      }
 
3)环绕通知:
      @Around("execution(* ISomeService.doSecond(..))")
      public Object surronding(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("环绕通知before");
            
            Object result = pjp.proceed();
            
            System.out.println("环绕通知after");
            
            return ((String)result).toUpperCase();
      }
 
4)异常通知:
      //异常通知
      @AfterThrowing("execution(* ISomeService.doThird(..))")
      public void afterThrowing() {
            System.out.println("异常通知");
      }
      
      @AfterThrowing(value="execution(* ISomeService.doThird(..))",throwing="ex")
      public void afterThrowing(Exception ex) {
            System.out.println("异常通知");
            System.out.println(ex.getMessage());
      }
 
5)最终通知:
      //最终通知
      @org.aspectj.lang.annotation.After("execution(* ISomeService.doThird(..))")
      public void after() {
            System.out.println("最终通知方法");
      }
 
定义切入点:
 
      //定义切入点
      @Pointcut("execution(* ISomeService.doThird(..))")
      private void doThirdPointCut() {}
      
      //异常通知,使用自定义切入点
      @AfterThrowing("doThirdPointCut()")
      public void afterThrowing1() {
            System.out.println("异常通知");
      }
 
 
AspectJ基于XML的AOP实现:
定义切入点:
            <!-- AOP配置 -->
            <aop:config>
                  <aop:pointcut expression="execution(* ISomeService.doFirst(..))" id="doFirstPointCut"/>     //连接点表达式,配置连接点
                  <aop:aspect ref="myAspect">
                        <aop:before method="before" pointcut-ref="doFirstPointCut"/>     //myAspect类中的before方法 before织入到连接点中
                  </aop:aspect>
            </aop:config>     
 
1) 前置通知:
            <!-- AOP配置 -->
            <aop:config>
                  <aop:aspect ref="myAspect">
                        <aop:before method="before" pointcut="execution(* ISomeService.doFirst(..))"/>
                  </aop:aspect>
            </aop:config>
要想执行before重载方法,需要给出参数全限定性类名:
<aop:before method="before(org.aspectj.lang.JoinPoint)" pointcut="execution(* ISomeService.doFirst(..))"/>
 
2)后置通知:
<aop:after-returning method="After(java.lang.String)" pointcut-ref="doSecondPointCut" returning="result"/>          //和方法的参数名一样
 
3)环绕通知:
<aop:around method="surronding" pointcut-ref="doSecondPointCut"/> //不需要添加ProceedingJoinPoint参数,因为参数是必须的
 
4)异常通知:
<aop:after-throwing method="afterThrowing(java.lang.Exception)" pointcut-ref="doThirdPointCut" throwing="ex"/>
 
5)最终通知:
<aop:after method="after" pointcut-ref="doThirdPointCut"/>
posted @ 2018-03-26 22:05  CoderLynn  阅读(202)  评论(0编辑  收藏  举报