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

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

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

1 簡介

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

2 Spring AOP vs AspectJ

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

2.1 織入方式

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

AspectJ是在運行前織入的,分為三類:

  • 編譯時織入
  • 編譯后織入
  • 加載時織入

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

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

2.2 Joinpoints

因為織入方式的區(qū)別,兩者所支持的Joinpoint也是不同的。像final的方法和靜態(tài)方法,無法通過動態(tài)代理來改變,所以Spring AOP無法支持。但AspectJ是直接在運行前織入實際的代碼,所以功能會強大很多。

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 性能

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

3 Spring Boot使用AspectJ

因為AspectJ比較強大,在項目中應(yīng)用會更多,所以這里只介紹它與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的對象

為了驗證AOP的功能,我們添加一個TestController,它有一個處理Get請求的方法,同時會調(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定義哪些類和方法會被捕抓來代理,這里配置的是controller下的所有方法。

@Before@Around則定義了一些處理邏輯。@Before是打印了方法名,而@Around是做了一個計時。

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

3.4 maven插件

因為是需要編譯時織入代碼,所以需要maven插件的支持:github.com/mojohaus/as…

配置好pom.xml文件即可。

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

mvn clean package

這時會顯示一些織入信息,大致如下:

[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))

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

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

3.5 執(zhí)行及測試

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

具體請參考:IDEA啟動Springboot但AOP失效

訪問如下:

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

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

3.6 一些遇到的錯誤

遇到錯誤:

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>

可能還會遇到無法識別Lombok的錯誤,配置如下則解決該問題:

<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場景應(yīng)用特別多,還是需要掌握的。

代碼請看GitHub: github.com/LarryDpk/pk…

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

相關(guān)文章

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

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

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

    java多線程編程學習(線程間通信)

    下面小編就為大家?guī)硪黄猨ava多線程編程學習(線程間通信)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Java調(diào)用CMD命令的方法與使用技巧

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

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

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

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

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

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

    java集合中的list詳解

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

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

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

    JavaWeb請求轉(zhuǎn)發(fā)和請求包含實現(xiàn)過程解析

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

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

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

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

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

最新評論