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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

aspectj切面织入

發(fā)布時(shí)間:2023/12/20 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 aspectj切面织入 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、介紹

AspectJ 是一個(gè) AOP 的具體實(shí)現(xiàn)框架。AOP(Aspect Oriented Programming)即面向切面編程,可以通過預(yù)編譯方式和運(yùn)行期動態(tài)代理實(shí)現(xiàn)在不修改源代碼的情況下給程序動態(tài)統(tǒng)一添加功能的一種技術(shù)。AspectJ不但可以通過預(yù)編譯方式(CTW)和運(yùn)行期動態(tài)代理的方式織入切面,還可以在載入(Load Time Weaving, LTW)時(shí)織入。AspectJ 擴(kuò)展了Java,定義了一些專門的AOP語法。

靜態(tài)代理唯一的缺點(diǎn)就是我們需要對每一個(gè)方法編寫我們的代理邏輯,造成了工作的繁瑣和復(fù)雜。AspectJ就是為了解決這個(gè)問題,在編譯成class字節(jié)碼的時(shí)候在方法周圍加上業(yè)務(wù)邏輯。復(fù)雜的工作由特定的編譯器幫我們做,而 aspectj-maven-plugin 插件即可幫我們完成靜態(tài)編譯代理。

aspectj-maven-plugin 的相關(guān)介紹 aspectj-maven-plugin 的相關(guān)介紹, 對應(yīng)的GitHub 地址 GitHub地址

aspectj-maven-plugin 插件是在 編譯階段 compile 對文件進(jìn)行增強(qiáng),可以從 生成的.class 文件可以看出.

二、靜態(tài)編譯代理

靜態(tài)編譯代理依賴ajc編譯器,通過maven插件支持。

  • 靜態(tài)代理所需要的配置:aspectj-maven-plugin插件
  • 并且如果切面來源于三方j(luò)ar包并且需要對當(dāng)前項(xiàng)目代碼做代理,那么需要通過配置指定插件中的AspectLibrary屬性來指定三方包來達(dá)到當(dāng)前項(xiàng)目的增強(qiáng),切面就是定義在當(dāng)前項(xiàng)目則無需此操作
  • 依賴AspectjTool 工具包

maven插件如下所示:

<plugin><groupId>org.codehaus.mojo</groupId><artifactId>aspectj-maven-plugin</artifactId><version>1.10</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding><complianceLevel>1.8</complianceLevel><verbose>true</verbose><showWeaveInfo>true</showWeaveInfo><aspectLibraries><aspectLibrary><groupId>com.example.pastor</groupId><artifactId>metric-reportor</artifactId></aspectLibrary></aspectLibraries></configuration><executions><execution><goals><goal>compile</goal><goal>test-compile</goal></goals></execution></executions> </plugin>

1、案例一

(1)pom.xml

<dependencies><!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.8.13</version></dependency><!-- 這個(gè)包不用引入,否則切面織入失敗 --><!--<dependency><groupId>org.aspectj</groupId><artifactId>aspectjtools</artifactId><version>1.8.13</version></dependency>--></dependencies><!--<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>--><build><plugins><plugin><groupId>org.codehaus.mojo</groupId><artifactId>aspectj-maven-plugin</artifactId><version>1.11</version><configuration><complianceLevel>1.8</complianceLevel><source>1.8</source><target>1.8</target><showWeaveInfo>true</showWeaveInfo><Xlint>ignore</Xlint><encoding>UTF-8</encoding><!-- 注意:IDEA下這個(gè)值要設(shè)置為false,否則運(yùn)行程序時(shí)IDEA會再次編譯,導(dǎo)致aspectj-maven-plugin編譯的結(jié)果被覆蓋 --><skip>false</skip></configuration><executions><execution><configuration><skip>false</skip></configuration><goals><goal>compile</goal></goals></execution></executions></plugin></plugins></build>

(2)業(yè)務(wù)方法

package com.scy.example.aspectj;public class UserServiceEnd {public void printLog() {System.out.println(" no param.....");} }

(3)切面代碼

package com.scy.example.aspectj;import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before;@Aspect public class MethodEndAspect {@Before("execution(* com.scy.example.aspectj.UserServiceEnd.printLog())")public void setStartTimeInThreadLocal(JoinPoint joinPoint) {System.out.println("before ...");}}

(4)編譯

輸入 編譯命令,mvn clean compile

PS E:\IdeaProjectSun\example> mvn clean compile [INFO] Scanning for projects... [INFO] [INFO] --------------------------< com.scy:example >--------------------------- [INFO] Building example 0.0.1-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ example --- [INFO] Deleting E:\IdeaProjectSun\example\target [INFO] [INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ example --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] Copying 16 resources [INFO] [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ example --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 8 source files to E:\IdeaProjectSun\example\target\classes [INFO] [INFO] --- aspectj-maven-plugin:1.11:compile (default) @ example --- [INFO] Showing AJC message detail for messages of types: [error, warning, fail] [INFO] Join point 'method-execution(void com.scy.example.aspectj.UserServiceEnd.printLog())' in Type 'com.scy.example.aspectj.UserServiceEnd' (UserServiceEnd.java:4 ) advised by before advice from 'com.scy.example.aspectj.MethodEndAspect' (MethodEndAspect.java:11) [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.306 s [INFO] Finished at: 2022-09-02T14:41:07+08:00 [INFO] ------------------------------------------------------------------------

(5)查看反編譯的class文件

// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) //package com.scy.example.aspectj;import org.aspectj.lang.JoinPoint; import org.aspectj.runtime.reflect.Factory;public class UserServiceEnd {public UserServiceEnd() {}public void printLog() {JoinPoint var1 = Factory.makeJP(ajc$tjp_0, this, this);MethodEndAspect.aspectOf().setStartTimeInThreadLocal(var1);System.out.println(" no param.....");}static {ajc$preClinit();} }

(6)運(yùn)行結(jié)果

before ...no param.....

2、案例二

對pom.xml 進(jìn)行優(yōu)化,其他不變。

<dependencies><!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.8.13</version></dependency><!-- https://mvnrepository.com/artifact/org.aspectj/aspectjtools --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjtools</artifactId><version>1.8.13</version></dependency></dependencies><!--<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>--><build><plugins><plugin><groupId>org.codehaus.mojo</groupId><artifactId>aspectj-maven-plugin</artifactId><version>1.11</version><configuration><complianceLevel>1.8</complianceLevel><source>1.8</source></configuration><executions><execution><goals><goal>compile</goal><goal>test-compile</goal></goals></execution></executions></plugin></plugins></build>

三、LoadTimeWeave加載期織入增強(qiáng)

加載類文件時(shí)通過instrument包去修改字節(jié)碼來插入增強(qiáng)邏輯

  • 首先要通過@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.AUTODETECT)
  • 其次要在項(xiàng)目啟動參數(shù)上要通過探針指定instrument包來動態(tài)修改織入
  • 在spring boot應(yīng)用加上此配置來讓應(yīng)用去讀取META-INF目錄下的aop.xml讀取切面已經(jīng)要織入的路徑配置(目前此配置在監(jiān)控的sdk中我已經(jīng)定義配置好)

工程配置類開啟LTW

@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.AUTODETECT) 1

java探針啟動參數(shù)

-javaagent:spring-instrument-5.2.5.RELEASE.jar 1

然后在類路徑下META-INF下面提供aop描述文件aop.xml,描述待織入的類路徑和切面類所在位置

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd"> <aspectj><weaver options="-showWeaveInfo -verbose"><include within="com.example.ltw.entity.*"/><include within="com.example.ltw.service.*"/></weaver><aspects><aspect name="com.example.ltw.ProfilingAspect"/><aspect name="com.qiyi.pastor.metricreportor.report.PastorReportAop"/></aspects> </aspectj>

四、小結(jié)

  • Aspectj并不是動態(tài)的在運(yùn)行時(shí)生成代理類,而是在編譯的時(shí)候就植入代碼到class文件
  • 由于是靜態(tài)織入的,所以性能相對來說比較好
  • Aspectj不受類的特殊限制,不管方法是private、或者static、或者final的,都可以代理
  • Aspectj不會代理除了限定方法之外任何其他諸如toString(),clone()等方法

五、參考

https://blog.csdn.net/healist/article/details/108824428

基于使用AspectJ實(shí)現(xiàn)AOP,注解AOP開發(fā)(基于xml文件、基于注解)_杭州小哥哥的博客-CSDN博客

總結(jié)

以上是生活随笔為你收集整理的aspectj切面织入的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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