zoukankan      html  css  js  c++  java
  • 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"/>
  • 相关阅读:
    数据库30条规范
    数据库索引原理
    HashMap的实现原理
    Google 和 Baidu 常用的搜索技巧
    Arrays工具类十大常用方法
    fastjson将json格式null转化空串
    SolrCloud的介绍
    网页背景图片自适应浏览器大小
    addlinkedserver
    常用
  • 原文地址:https://www.cnblogs.com/coderlynn/p/8654349.html
Copyright © 2011-2022 走看看