偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

New 的對象也能被 Spring 注入?AspectJ LTW 打破限制!

開發(fā) 前端
Spring 提供了基于 AspectJ 加載期織入(LTW)的解決方案。通過?@Configurable?注解與?META-INF/aop.xml?配置,結(jié)合 JVM?-javaagent?機制,可在類加載時動態(tài)織入依賴注入邏輯,使?new?出的對象也能自動裝配 Spring Bean。

環(huán)境:SpringBoot3.4.2

1. 簡介

在傳統(tǒng) Spring 應(yīng)用中,依賴注入(DI)僅限于由 Spring 容器管理的 Bean。然而,在實際開發(fā)中,常遇到需通過 new 關(guān)鍵字直接創(chuàng)建對象的場景,如領(lǐng)域?qū)嶓w、DTO 轉(zhuǎn)換、工廠模式或第三方庫回調(diào)。這些對象脫離了 Spring 容器的生命周期,無法使用 @Autowired 注入服務(wù),導(dǎo)致業(yè)務(wù)邏輯與數(shù)據(jù)訪問耦合,難以測試與維護。

為此,Spring 提供了基于 AspectJ 加載期織入(LTW)的解決方案。通過 @Configurable 注解與 META-INF/aop.xml 配置,結(jié)合 JVM -javaagent 機制,可在類加載時動態(tài)織入依賴注入邏輯,使 new 出的對象也能自動裝配 Spring Bean。該技術(shù)突破容器邊界,實現(xiàn)了真正意義上的全鏈路依賴注入,為復(fù)雜場景下的對象管理提供了強大支持。

本篇文章會詳細介紹LTW技術(shù)的完整實現(xiàn)過程。

2.實戰(zhàn)案例

2.1 引入Aspect依賴

要啟用基于 AspectJ 的配置,需要添加 AspectJ Weaver 依賴項。

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
</dependency>

引入 spring-aspects 依賴以支持 @Configurable 等注解的織入,提供 AspectJ 與 Spring 集成的切面實現(xiàn),是實現(xiàn)加載期織入(LTW)和自動依賴注入的基礎(chǔ)。

2.2 開啟非管理Bean注入功能

@SpringBootApplication
@EnableSpringConfigured
@EnableLoadTimeWeaving
public class App {
}
  • @EnableSpringConfigured:注解向當(dāng)前應(yīng)用上下文發(fā)出信號,以將依賴注入應(yīng)用于那些在Spring Bean工廠之外實例化的非托管類(通常是使用@Configurable注解標注的類)。
  • @EnableLoadTimeWeaving:注解的作用是啟用 Spring 的加載期織入(Load-Time Weaving, LTW)機制,允許在類加載時由 AspectJ 對字節(jié)碼進行增強,從而實現(xiàn)對 new 創(chuàng)建的對象(如標記了 @Configurable 的類)進行依賴注入,突破 Spring 容器的管理邊界。

2.3 定義不受Spring管理的Bean

@Configurable
public class CommonService {
  @Resource
  private UserService userService ;


  public void getUser() {
    this.userService.query() ; 
  }
}

@Configurable 注解指示 Spring 應(yīng)通過 AspectJ 加載期織入(LTW)機制,對該類的實例進行依賴注入。在該示例中,CommonService 類可以通過 new 關(guān)鍵字創(chuàng)建,并借助 @Configurable,Spring 仍能為其注入所需的 Bean。該類中通過 @Resource 注解注入了由 Spring 容器管理的 UserService Bean,使得即使脫離容器直接實例化,也能正常使用 userService.query() 等業(yè)務(wù)方法,實現(xiàn)與 Spring 管理對象的無縫集成。

定義UserService受管理的Bean

@Service
public class UserService {
  public void query() {
    System.err.println("查詢用戶信息...") ;
  }
}

2.4 測試new創(chuàng)建CommonService

接下來,我們直接通過定義Runner進行測試,通過new創(chuàng)建CommonService后測試是否可以正確的注入UserService。

@Component
public class TestRunner implements CommandLineRunner {
  @Override
  public void run(String... args) throws Exception {
    CommonService cs = new CommonService() ;
    cs.getUser() ;
  }
}

2.5 啟用AspectJ織入

要使 @EnableSpringConfigured 生效,必須啟用 AspectJ 織入。這可以在運行時或編譯時完成。

運行時織入,添加 spring-instrument 依賴,并將 AspectJ 織入器作為 Java Agent 啟用。

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-instrument</artifactId>
</dependency>

2.6 啟動應(yīng)用測試

在完成以上步驟后,啟動應(yīng)用,你將看到如下的錯誤:

圖片圖片

錯誤信息非常明確的告訴你還需要使用-javaagent:spring-instrument-xxx.jar參數(shù)。

-javaagent:D:\java\maven\org\springframework\spring-instrument\6.2.7\spring-instrument-6.2.7.jar

再次啟動應(yīng)用,這次不會再有錯誤,但是將有一堆如下信息:

圖片圖片

一堆error日志,并且我們程序也正確的運行了。

解決error日志

我們可以在META-INF下新建aop.xml文件,進行相關(guān)的配置,如下:

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
  <weaver options="-Xlint:ignore">
    <include within="com.pack..*"/>
  </weaver>
</aspectj>
  • <weaver optinotallow="-Xlint:ignore">:啟用 AspectJ 織入器,并忽略所有織入過程中的警告信息(如無法找到類、注解等),避免日志污染,但需確保忽略不會掩蓋關(guān)鍵問題。
  • <include within="com.pack..*"/>:指定僅對 com.pack 包及其子包下的類進行織入處理,提高性能并避免對無關(guān)類(如第三方庫)進行不必要的織入。

2.7 添加增強功能

我們已經(jīng)使用了 META-INF/aop.xml 文件,但它不僅僅用于簡單配置(如忽略警告信息),還可以在其中定義切面織入規(guī)則,實現(xiàn)對目標類的 AOP 增強,從而擴展功能。

新建切面
@Aspect
public class ProfilingAspect {
  @Around("methodsToBeProfiled()")
  public Object profile(ProceedingJoinPoint pjp) throws Throwable {
    StopWatch sw = new StopWatch(getClass().getSimpleName());
    try {
      sw.start(pjp.getSignature().getName());
      return pjp.proceed();
    } finally {
      sw.stop();
      System.err.println(sw.prettyPrint());
    }
  }
  @Pointcut("execution(public * com.pack..*.*(..))")
  public void methodsToBeProfiled() {
  }
}
修改aop.xml文件
<aspectj>
  <weaver options="-Xlint:ignore">
    <include within="com.pack..*"/>
  </weaver>
  <aspects>
    <aspect name="com.pack.mgr.aspect.ProfilingAspect"/>
  </aspects>
</aspectj>

再次啟動應(yīng)用,控制臺輸出:

圖片圖片圖片

責(zé)任編輯:武曉燕 來源: Springboot全家桶實戰(zhàn)案例
相關(guān)推薦

2020-06-23 08:10:30

Spring容器權(quán)限

2018-01-26 09:01:16

對象存儲Java

2022-07-01 06:44:42

微信應(yīng)用偽裝應(yīng)用轉(zhuǎn)生

2023-10-23 16:14:00

數(shù)據(jù)孤島數(shù)據(jù)管理

2021-12-22 10:35:04

云計算

2021-07-02 09:12:39

數(shù)字化

2022-09-26 11:51:47

電信機房光纖連接

2020-12-22 09:34:20

JavaScript開發(fā)技術(shù)

2021-10-19 21:30:45

微軟Windows 11Windows

2009-01-18 09:19:00

DHCPVlANIP

2022-03-18 12:08:10

微分計算模式

2021-11-11 11:31:54

擺動序列數(shù)字

2019-08-20 00:08:18

MySQL數(shù)據(jù)庫數(shù)據(jù)

2019-04-12 09:24:46

Spring Clou服務(wù)注冊

2011-05-31 10:00:21

Android Spring 依賴注入

2011-03-31 11:03:15

2025-04-11 08:42:10

Java對象TLAB

2019-07-09 08:44:00

DeepfakeGAN人工智能

2012-07-17 09:16:16

SpringSSH

2011-07-13 10:32:09

開源
點贊
收藏

51CTO技術(shù)棧公眾號