日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring3系列12-Spring AOP AspectJ

發(fā)布時間:2023/12/20 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring3系列12-Spring AOP AspectJ 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文講述使用AspectJ框架實現(xiàn)Spring AOP。

再重復一下Spring AOP中的三個概念,

  • Advice:向程序內(nèi)部注入的代碼。
  • Pointcut:注入Advice的位置,切入點,一般為某方法。
  • Advisor:Advice和Pointcut的結(jié)合單元,以便將Advice和Pointcut分開實現(xiàn)靈活配置。
  • AspectJ是基于注釋(Annotation)的,所以需要JDK5.0以上的支持。

    AspectJ支持的注釋類型如下:

  • @Before
  • @After
  • @AfterReturning
  • @AfterThrowing
  • @Around
  • ?

    首先定義一個簡單的bean,CustomerBo實現(xiàn)了接口ICustomerBo

    ICustomerBo.java如下:

    package com.lei.demo.aop.aspectj;public interface ICustomerBo {void addCustomer();void deleteCustomer();String AddCustomerReturnValue();void addCustomerThrowException() throws Exception;void addCustomerAround(String name);}

    ?

    ?CustomerBo.java如下:

    ?

    package com.lei.demo.aop.aspectj;public class CustomerBo implements ICustomerBo {public void addCustomer() {System.out.println("addCustomer() is running ...");}public void deleteCustomer() {System.out.println("deleteCustomer() is running ...");}public String AddCustomerReturnValue() {System.out.println("AddCustomerReturnValue() is running ...");return "abc";}public void addCustomerThrowException() throws Exception {System.out.println("addCustomerThrowException() is running ...");throw new Exception("Generic Error");}public void addCustomerAround(String name) {System.out.println("addCustomerAround() is running ,args:"+name);}}

    ?

    一、????? 簡單的AspectJ,Advice和Pointcut結(jié)合在一起

    首先沒有引入Pointcut之前,Advice和Pointcut是混在一起的

    步驟,只需要兩步,如下:

  • 創(chuàng)建一個Aspect類
  • 配置Spring配置文件
  • ?

    第一步,創(chuàng)建Aspect類

    LoggingAspect.java如下:

    package com.lei.demo.aop.aspectj;import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before;@Aspect public class LoggingAspect {@Before("execution(public * com.lei.demo.aop.aspectj.CustomerBo.addCustomer(..))")public void logBefore(JoinPoint joinPoint){System.out.println("logBefore() is running ...");System.out.println("hijacked:"+joinPoint.getSignature().getName());System.out.println("**********");}@After("execution(public * com.lei.demo.aop.aspectj.CustomerBo.deleteCustomer(..))")public void logAfter(JoinPoint joinPoint){System.out.println("logAfter() is running ...");System.out.println("hijacked:"+joinPoint.getSignature().getName());System.out.println("**********");} }

    ?

    解釋:

    1.??必須使用@AspectLoggingAspect聲明之前注釋,以便被框架掃描到

    2.? 此例AdvicePointcut結(jié)合在一起,類中的具體方法logBeforelogAfter即為Advice,是要注入的代碼,Advice方法上的表達式為Pointcut表達式,即定義了切入點,上例中@Before注釋的表達式代表執(zhí)行CustomerBo.addCustomer方法時注入logBefore代碼。

    3.??LoggingAspect方法上加入@Before或者@After等注釋

    4.??"execution(public * com.lei.demo.aop.aspectj.CustomerBo.addCustomer(..))"Aspect的切入點表達式,其中,*代表返回類型,后邊的就要定義要攔截的方法名,這里寫的的是com.lei.demo.aop.aspectj.CustomerBo.addCustomer表示攔截CustomerBo中的addCustomer方法,(..)代表參數(shù)匹配,此處表示匹配任意數(shù)量的參數(shù),可以是0個也可以是多個,如果你確定這個方法不需要使用參數(shù)可以直接用(),還可以使用(*)來匹配一個任意類型的參數(shù),還可以使用?(* , String),這樣代表匹配兩個參數(shù),第二個參數(shù)必須是String?類型的參數(shù)

    5.??AspectJ表達式,可以對整個包定義,例如,execution(* com.lei.service..*.*(..))表示切入點是com.lei.sevice包中的任意一個類的任意方法,具體的表達式請自行百度。

    ?

    第二步,配置Spring配置文件,

    配置Spring-AOP-AspectJ.xml文件,如下:

    <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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.0.xsd"><aop:aspectj-autoproxy/><bean id="customerBo" class="com.lei.demo.aop.aspectj.CustomerBo"/><bean id="logAspect" class="com.lei.demo.aop.aspectj.LoggingAspect" /></beans>

    ?

    解釋:

    1.??????<aop:aspectj-autoproxy/>啟動AspectJ支持,這樣Spring會自動尋找用@Aspect注釋過的類,其他的配置與spring普通bean配置一樣。

    ?

    測試:

    執(zhí)行App.java如下:

    package com.lei.demo.aop.aspectj;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {ApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] { "Spring-AOP-AspectJ.xml" });ICustomerBo customer=(ICustomerBo)appContext.getBean("customerBo");customer.addCustomer();System.out.println("-------------------------------------------");customer.deleteCustomer();} }

    ?

    結(jié)果:

    logBefore() is running ...

    hijacked:addCustomer

    **********

    addCustomer() is running ...

    -------------------------------------------

    deleteCustomer() is running ...

    logAfter() is running ...

    hijacked:deleteCustomer

    **********

    ?

    二、????? 將Advice和Pointcut分開

    需要三步,

  • 創(chuàng)建Pointcut
  • 創(chuàng)建Advice
  • 配置Spring的配置文件
  • ?

    第一步,PointcutsDefinition.java定義了Pointcut,如下:

    package com.lei.demo.aop.aspectj;import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut;@Aspect public class PointcutsDefinition {@Pointcut("execution(* com.lei.demo.aop.aspectj.CustomerBo.*(..))")public void customerLog() {} }

    ?

    解釋:

    1. 類聲明前加入@Aspect注釋,以便被框架掃描到。

    2. @Pointcut是切入點聲明,指定需要注入的代碼的位置,如上例中指定切入點為CustomerBo類中的所有方法,在實際業(yè)務中往往是指定切入點到一個邏輯層,例如?execution (* com.lei.business.service.*.*(..)),表示aop切入點為service包中所有類的所有方法,具體的表達式后邊會有介紹。

    3. 方法customerLog是一個簽名,在Advice中可以用此簽名代替切入點表達式,所以不需要在方法體內(nèi)編寫實際代碼,只起到助記功能,例如此處代表操作CustomerBo類時需要的切入點。

    ?

    第二步,創(chuàng)建Advice類

    LoggingAspect.java如下:

    package com.lei.demo.aop.aspectj;import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before;@Aspect public class LoggingAspect {@Before("com.lei.demo.aop.aspectj.PointcutsDefinition.customerLog()")public void logBefore(JoinPoint joinPoint){System.out.println("logBefore() is running ...");System.out.println("hijacked:"+joinPoint.getSignature().getName());System.out.println("**********");}@After("com.lei.demo.aop.aspectj.PointcutsDefinition.customerLog()")public void logAfter(JoinPoint joinPoint){System.out.println("logAfter() is running ...");System.out.println("hijacked:"+joinPoint.getSignature().getName());System.out.println("**********");} }

    ?

    注釋:

    1.???????@Before@After使用PointcutsDefinition中的方法簽名代替Pointcut表達式找到相應的切入點,即通過簽名找到PointcutsDefinitioncustomerLog簽名上的Pointcut表達式,表達式指定切入點為CustomerBo類中的所有方法。所以此例中AdviceLoggingAdvice,為CustomerBo中的所有方法都加入了@Before@After兩種類型的兩種操作。

    2.???????對于PointcutsDefinition來說,主要職責是定義Pointcut,可以在其中第一多個切入點,并且可以用便于記憶的方法簽名進行定義。

    3.???????單獨定義Pointcut的好處是,一是通過使用有意義的方法名,而不是難讀的Pointcut表達式,使代碼更加直觀;二是Pointcut可以實現(xiàn)共享,被多個Advice直接調(diào)用。若有多個Advice調(diào)用某個Pointcut,而這個Pointcut的表達式在將來有改變時,只需修改一個地方,維護更加方便。

    ?

    第三步,配置Spring配置文件,配置文件并沒有改變

    配置Spring-AOP-AspectJ.xml文件,如下:

    <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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.0.xsd"><aop:aspectj-autoproxy/><bean id="customerBo" class="com.lei.demo.aop.aspectj.CustomerBo"/><bean id="logAspect" class="com.lei.demo.aop.aspectj.LoggingAspect" /></beans>

    ?

    App.java不變,運行測試代碼App.java

    輸出結(jié)果:

    logBefore() is running ...

    hijacked:addCustomer

    **********

    addCustomer() is running ...

    logAfter() is running ...

    hijacked:addCustomer

    **********

    -------------------------------------------

    logBefore() is running ...

    hijacked:deleteCustomer

    **********

    deleteCustomer() is running ...

    logAfter() is running ...

    hijacked:deleteCustomer

    **********

    ?

    三、???? 切入點表達式

    Spring3.0.5幫助文檔中的切入點表達式如下:

    ?

    Some examples of common pointcut expressions are given below.

    ?

    the execution of any public method:

    execution(public * *(..))


    the execution of any method with a name beginning with "set":

    execution(* set*(..))


    the execution of any method defined by the AccountService interface:

    execution(* com.xyz.service.AccountService.*(..))


    the execution of any method defined in the service package:

    execution(* com.xyz.service.*.*(..))


    the execution of any method defined in the service package or a sub-package:

    execution(* com.xyz.service..*.*(..))


    any join point (method execution only in Spring AOP) within the service package:

    within(com.xyz.service.*)


    any join point (method execution only in Spring AOP) within the service package or a sub-package:

    within(com.xyz.service..*)


    any join point (method execution only in Spring AOP) where the proxy implements the AccountService interface:

    this(com.xyz.service.AccountService)

    'this' is more commonly used in a binding form :- see the following section on advice for how to make the proxy object available in the advice body.

    ?

    any join point (method execution only in Spring AOP) where the target object implements the AccountService interface:

    target(com.xyz.service.AccountService)

    'target' is more commonly used in a binding form :- see the following section on advice for how to make the target object available in the advice body.

    ?

    any join point (method execution only in Spring AOP) which takes a single parameter, and where the argument passed at runtime is Serializable:

    args(java.io.Serializable)
    'args' is more commonly used in a binding form :- see the following section on advice for how to make the method arguments available in the advice body.

    Note that the pointcut given in this example is different to execution(* *(java.io.Serializable)): the args version matches if the argument passed at runtime is Serializable, the execution version matches if the method signature declares a single parameter of type Serializable.

    ?

    any join point (method execution only in Spring AOP) where the target object has an @Transactional annotation:

    @target(org.springframework.transaction.annotation.Transactional)

    '@target' can also be used in a binding form :- see the following section on advice for how to make the annotation object available in the advice body.

    ?

    any join point (method execution only in Spring AOP) where the declared type of the target object has an @Transactional annotation:

    @within(org.springframework.transaction.annotation.Transactional)

    '@within' can also be used in a binding form :- see the following section on advice for how to make the annotation object available in the advice body.

    ?

    any join point (method execution only in Spring AOP) where the executing method has an @Transactional annotation:

    @annotation(org.springframework.transaction.annotation.Transactional)

    '@annotation' can also be used in a binding form :- see the following section on advice for how to make the annotation object available in the advice body.

    ?

    any join point (method execution only in Spring AOP) which takes a single parameter, and where the runtime type of the argument passed has the@Classified annotation:

    @args(com.xyz.security.Classified)

    '@args' can also be used in a binding form :- see the following section on advice for how to make the annotation object(s) available in the advice body.

    ?

    any join point (method execution only in Spring AOP) on a Spring bean named 'tradeService':

    bean(tradeService)


    any join point (method execution only in Spring AOP) on Spring beans having names that match the wildcard expression '*Service':

    bean(*Service)

    轉(zhuǎn)載于:https://www.cnblogs.com/jcomet/p/5570460.html

    總結(jié)

    以上是生活随笔為你收集整理的Spring3系列12-Spring AOP AspectJ的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。