欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring AOP與AspectJ的對(duì)比及應(yīng)用詳解

 更新時(shí)間:2023年02月08日 17:20:53   作者:南瓜慢說(shuō)  
這篇文章主要為大家介紹了Spring AOP與AspectJ的對(duì)比及應(yīng)用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1 簡(jiǎn)介

AOP,即面向切面編程是很常用的技術(shù),特別是在Java Web開(kāi)發(fā)中。而最流行的AOP框架分別是Spring AOP和AspectJ。

2 Spring AOP vs AspectJ

Spring AOP是基于Spring IoC實(shí)現(xiàn)的,它解決大部分常見(jiàn)的需求,但它并不是一個(gè)完整的AOP解決方案。對(duì)于非Spring容器管理的對(duì)象,它更沒(méi)有辦法了。而AspectJ旨在提供完整的AOP方案,因此也會(huì)更復(fù)雜。

2.1 織入方式

兩者織入方式有極大的不同,這也是它們的本質(zhì)區(qū)別,它們實(shí)現(xiàn)代理的方式不同。

AspectJ是在運(yùn)行前織入的,分為三類:

  • 編譯時(shí)織入
  • 編譯后織入
  • 加載時(shí)織入

因此需要AspectJ編譯器(ajc)的支持。

而Spring AOP是運(yùn)行時(shí)織入的,主要使用了兩種技術(shù):JDK動(dòng)態(tài)代理和CGLIB代理。對(duì)于接口使用JDK Proxy,而繼承的使用CGLIB。

2.2 Joinpoints

因?yàn)榭椚敕绞降膮^(qū)別,兩者所支持的Joinpoint也是不同的。像final的方法和靜態(tài)方法,無(wú)法通過(guò)動(dòng)態(tài)代理來(lái)改變,所以Spring AOP無(wú)法支持。但AspectJ是直接在運(yùn)行前織入實(shí)際的代碼,所以功能會(huì)強(qiáng)大很多。

JoinpointSpring AOP SupportedAspectJ Supported
Method CallNoYes
Method ExecutionYesYes
Constructor CallNoYes
Constructor ExecutionNoYes
Static initializer executionNoYes
Object initializationNoYes
Field referenceNoYes
Field assignmentNoYes
Handler executionNoYes
Advice executionNoYes

2.3 性能

編譯織入會(huì)比較運(yùn)行時(shí)織入快很多,Spring AOP是使用代理模式在運(yùn)行時(shí)才創(chuàng)建對(duì)應(yīng)的代理類,效率沒(méi)有AspectJ高。

3 Spring Boot使用AspectJ

因?yàn)锳spectJ比較強(qiáng)大,在項(xiàng)目中應(yīng)用會(huì)更多,所以這里只介紹它與Spring Boot的集成。

3.1 引入依賴

引入以下依賴,在Spring Boot基礎(chǔ)上加了Lombok和aspectj:

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>${aspectj.version}</version>
  </dependency>
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>${aspectj.version}</version>
  </dependency>
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
    <scope>provided</scope>
  </dependency>
</dependencies>

3.2 被AOP的對(duì)象

為了驗(yàn)證AOP的功能,我們添加一個(gè)TestController,它有一個(gè)處理Get請(qǐng)求的方法,同時(shí)會(huì)調(diào)用private的成員方法和靜態(tài)方法:

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {
    @GetMapping("/hello")
    public String hello() {
        log.info("------hello() start---");
        test();
        staticTest();
        log.info("------hello() end---");
        return "Hello, pkslow.";
    }
    private void test() {
        log.info("------test() start---");
        log.info("test");
        log.info("------test() end---");
    }
    private static void staticTest() {
        log.info("------staticTest() start---");
        log.info("staticTest");
        log.info("------staticTest() end---");
    }
}

3.3 配置Aspect

配置切面如下:

@Aspect
@Component
@Slf4j
//@EnableAspectJAutoProxy
public class ControllerAspect {
    @Pointcut("execution(* com.pkslow.springboot.controller..*.*(..))")
    private void testControllerPointcut() {
    }
    @Before("testControllerPointcut()")
    public void doBefore(JoinPoint joinPoint){
        log.info("------pkslow aop doBefore start------");
        String method = joinPoint.getSignature().getName();
        String declaringTypeName = joinPoint.getSignature().getDeclaringTypeName();
        log.info("Method: {}.{}" ,declaringTypeName, method);
        log.info("------pkslow aop doBefore end------");
    }
    @Around("testControllerPointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("------pkslow aop doAround start------");
        long start = System.nanoTime();
        Object obj = joinPoint.proceed();
        long end = System.nanoTime();
        log.info("Execution Time: " + (end - start) + " ns");
        log.info("------pkslow aop doAround end------");
        return obj;
    }
}

@Pointcut定義哪些類和方法會(huì)被捕抓來(lái)代理,這里配置的是controller下的所有方法。

@Before@Around則定義了一些處理邏輯。@Before是打印了方法名,而@Around是做了一個(gè)計(jì)時(shí)。

注意:是不需要配置@EnableAspectJAutoProxy的。

3.4 maven插件

因?yàn)槭切枰幾g時(shí)織入代碼,所以需要maven插件的支持:github.com/mojohaus/as…

配置好pom.xml文件即可。

然后執(zhí)行命令打包:

mvn clean package

這時(shí)會(huì)顯示一些織入信息,大致如下:

[INFO] Join point 'method-execution(java.lang.String com.pkslow.springboot.controller.TestController.hello())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:14) advised by around advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
[INFO] Join point 'method-execution(java.lang.String com.pkslow.springboot.controller.TestController.hello())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:14) advised by before advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
[INFO] Join point 'method-execution(void com.pkslow.springboot.controller.TestController.test())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:22) advised by around advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
[INFO] Join point 'method-execution(void com.pkslow.springboot.controller.TestController.test())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:22) advised by before advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
[INFO] Join point 'method-execution(void com.pkslow.springboot.controller.TestController.staticTest())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:28) advised by around advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
[INFO] Join point 'method-execution(void com.pkslow.springboot.controller.TestController.staticTest())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:28) advised by before advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))

看到以上信息,說(shuō)明成功織入了代碼,具體可以查看生成的class文件。

可以看到有許多代碼都不是我們寫(xiě)的,而是織入生成。

3.5 執(zhí)行及測(cè)試

編譯成功后,我們就執(zhí)行代碼。如果是通過(guò)IDEA來(lái)執(zhí)行,則在運(yùn)行前不需要再build了,因?yàn)橐呀?jīng)通過(guò)maven build過(guò)了包。通過(guò)IDEA自帶的編譯器build,可能無(wú)法織入?;蛘哌x擇ajc作為編譯器。

具體請(qǐng)參考:IDEA啟動(dòng)Springboot但AOP失效

訪問(wèn)如下:

GET http://localhost:8080/test/hello

則日志如下,成功實(shí)現(xiàn)AOP功能:

3.6 一些遇到的錯(cuò)誤

遇到錯(cuò)誤:

ajc Syntax error, annotations are only available if source level is 1.5 or greater

需要配置插件:

<complianceLevel>${java.version}</complianceLevel>
<source>${java.version}</source>
<target>${java.version}</target>

可能還會(huì)遇到無(wú)法識(shí)別Lombok的錯(cuò)誤,配置如下則解決該問(wèn)題:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>aspectj-maven-plugin</artifactId>
  <version>1.14.0</version>
  <configuration>
    <complianceLevel>${java.version}</complianceLevel>
    <source>${java.version}</source>
    <target>${java.version}</target>
    <proc>none</proc>
    <showWeaveInfo>true</showWeaveInfo>
    <forceAjcCompile>true</forceAjcCompile>
    <sources/>
    <weaveDirectories>
      <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
    </weaveDirectories>
  </configuration>
  <executions>
    <execution>
      <goals>
        <goal>compile</goal>
      </goals>
    </execution>
  </executions>
</plugin>

4 總結(jié)

AOP場(chǎng)景應(yīng)用特別多,還是需要掌握的。

代碼請(qǐng)看GitHub: github.com/LarryDpk/pk…

以上就是Spring AOP與AspectJ的對(duì)比及應(yīng)用詳解的詳細(xì)內(nèi)容,更多關(guān)于Spring AOP對(duì)比AspectJ應(yīng)用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 簡(jiǎn)單了解Spring Web相關(guān)模塊運(yùn)行原理

    簡(jiǎn)單了解Spring Web相關(guān)模塊運(yùn)行原理

    這篇文章主要介紹了簡(jiǎn)單了解Spring Web相關(guān)模塊運(yùn)行原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • java多線程編程學(xué)習(xí)(線程間通信)

    java多線程編程學(xué)習(xí)(線程間通信)

    下面小編就為大家?guī)?lái)一篇java多線程編程學(xué)習(xí)(線程間通信)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • Java調(diào)用CMD命令的方法與使用技巧

    Java調(diào)用CMD命令的方法與使用技巧

    在實(shí)際的開(kāi)發(fā)中我們有可能會(huì)遇到?java調(diào)用?cmd命令的情況,這篇文章主要給大家介紹了關(guān)于Java調(diào)用CMD命令的方法與使用的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-09-09
  • IntelliJ IDEA2020.1版本更新pom文件自動(dòng)導(dǎo)包的方法

    IntelliJ IDEA2020.1版本更新pom文件自動(dòng)導(dǎo)包的方法

    這篇文章主要介紹了IntelliJ IDEA2020.1版本更新pom文件自動(dòng)導(dǎo)包的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Android Studio中ButterKnife插件的安裝與使用詳解

    Android Studio中ButterKnife插件的安裝與使用詳解

    本篇文章主要介紹了Android Studio中ButterKnife插件的安裝與使用詳解,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • java集合中的list詳解

    java集合中的list詳解

    這篇文章主要介紹了java集合中的list詳解,還是比較不錯(cuò)的,這里分享給大家,需要的朋友可以參考下。
    2017-11-11
  • 在Spring AOP中代理對(duì)象創(chuàng)建的步驟詳解

    在Spring AOP中代理對(duì)象創(chuàng)建的步驟詳解

    今天和小伙伴們聊一聊 Spring AOP 中的代理對(duì)象是怎么創(chuàng)建出來(lái)的,透過(guò)這個(gè)過(guò)程再去熟悉一下 Bean 的創(chuàng)建過(guò)程,感興趣的小伙伴跟著小編一起來(lái)看看吧
    2023-08-08
  • JavaWeb請(qǐng)求轉(zhuǎn)發(fā)和請(qǐng)求包含實(shí)現(xiàn)過(guò)程解析

    JavaWeb請(qǐng)求轉(zhuǎn)發(fā)和請(qǐng)求包含實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了JavaWeb請(qǐng)求轉(zhuǎn)發(fā)和請(qǐng)求包含實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • 關(guān)于連接遠(yuǎn)程redis的流程

    關(guān)于連接遠(yuǎn)程redis的流程

    這篇文章主要介紹了關(guān)于連接遠(yuǎn)程redis的流程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • java外部類與內(nèi)部類簡(jiǎn)介

    java外部類與內(nèi)部類簡(jiǎn)介

    這篇文章簡(jiǎn)單介紹了java外部類與內(nèi)部類,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12

最新評(píng)論