大数跨境
0
0

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

new 的对象也能被 Spring 注入?AspectJ LTW 打破限制! Spring全家桶实战案例
2025-10-02
0
导读:new 的对象也能被 Spring 注入?AspectJ LTW 打破限制!
Spring Boot 3实战案例锦集PDF电子书已更新至130篇!

🎉🎉《Spring Boot实战案例合集》目前已更新177个案例,我们将持续不断的更新。文末有电子书目录。

💪💪永久更新承诺

我们郑重承诺,所有订阅合集的粉丝都将享受永久免费的后续更新服务

💌💌如何获取
订阅我们的合集点我订阅,并通过私信联系我们,我们将第一时间将电子书发送给您。

→ 现在就订阅合集

环境:SpringBoot3.4.2



1. 简介

在传统 Spring 应用中,依赖注入(DI)仅限于由 Spring 容器管理的 Bean。然而,在实际开发中,常遇到需通过 new 关键字直接创建对象的场景,如领域实体、DTO 转换、工厂模式或第三方库回调。这些对象脱离了 Spring 容器的生命周期,无法使用 @Autowired 注入服务,导致业务逻辑与数据访问耦合,难以测试与维护。

为此,Spring 提供了基于 AspectJ 加载期织入(LTW)的解决方案。通过 @Configurable 注解与 META-INF/aop.xml 配置,结合 JVM -javaagent 机制,可在类加载时动态织入依赖注入逻辑,使 new 出的对象也能自动装配 Spring Bean。该技术突破容器边界,实现了真正意义上的全链路依赖注入,为复杂场景下的对象管理提供了强大支持。

本篇文章会详细介绍LTW技术的完整实现过程。

2.实战案例

2.1 引入Aspect依赖

要启用基于 AspectJ 的配置,需要添加 AspectJ Weaver 依赖项。

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

引入 spring-aspects 依赖以支持 @Configurable 等注解的织入,提供 AspectJ 与 Spring 集成的切面实现,是实现加载期织入(LTW)和自动依赖注入的基础。

2.2 开启非管理Bean注入功能

@SpringBootApplication@EnableSpringConfigured@EnableLoadTimeWeavingpublic class App {}
  • @EnableSpringConfigured:注解向当前应用上下文发出信号,以将依赖注入应用于那些在Spring Bean工厂之外实例化的非托管类(通常是使用@Configurable注解标注的类)。

  • @EnableLoadTimeWeaving:注解的作用是启用 Spring 的加载期织入(Load-Time Weaving, LTW)机制,允许在类加载时由 AspectJ 对字节码进行增强,从而实现对 new 创建的对象(如标记了 @Configurable 的类)进行依赖注入,突破 Spring 容器的管理边界。

2.3 定义不受Spring管理的Bean

@Configurablepublic class CommonService {  @Resource  private UserService userService ;
  public void getUser() {    this.userService.query() ;   }}

@Configurable 注解指示 Spring 应通过 AspectJ 加载期织入(LTW)机制,对该类的实例进行依赖注入。在该示例中,CommonService 类可以通过 new 关键字创建,并借助 @Configurable,Spring 仍能为其注入所需的 Bean。该类中通过 @Resource 注解注入了由 Spring 容器管理的 UserService Bean,使得即使脱离容器直接实例化,也能正常使用 userService.query() 等业务方法,实现与 Spring 管理对象的无缝集成。

定义UserService受管理的Bean

@Servicepublic class UserService {  public void query() {    System.err.println("查询用户信息...") ;  }}

2.4 测试new创建CommonService

接下来,我们直接通过定义Runner进行测试,通过new创建CommonService后测试是否可以正确的注入UserService。

@Componentpublic 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 启动应用测试

在完成以上步骤后,启动应用,你将看到如下的错误:

错误信息非常明确的告诉你还需要使用-javaagent:spring-instrument-xxx.jar参数。

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

再次启动应用,这次不会再有错误,但是将有一堆如下信息:

一堆error日志,并且我们程序也正确的运行了。

解决error日志

我们可以在META-INF下新建aop.xml文件,进行相关的配置,如下:

<!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 options="-Xlint:ignore">:启用 AspectJ 织入器,并忽略所有织入过程中的警告信息(如无法找到类、注解等),避免日志污染,但需确保忽略不会掩盖关键问题。

  • <include within="com.pack..*"/>:指定仅对 com.pack 包及其子包下的类进行织入处理,提高性能并避免对无关类(如第三方库)进行不必要的织入。

2.7 添加增强功能

我们已经使用了 META-INF/aop.xml 文件,但它不仅仅用于简单配置(如忽略警告信息),还可以在其中定义切面织入规则,实现对目标类的 AOP 增强,从而扩展功能。

新建切面

@Aspectpublic 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>

再次启动应用,控制台输出:



以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏

推荐文章

优化!高并发下 Spring Boot 乐观锁 + 悲观锁性能调优

Spring Boot中JSON日期处理的5种骚操作

告别OOM!Spring Boot 流式导出百万数据:支持MyBatis/JPA/Jdbc

强大!Spring Boot 动态JSON字段按需输出,一个注解搞定

Spring Boot API接口性能提升:10项核心优化技能全解析

惊呆了!Spring Boot 通过这7种策略实现注入

优雅!Spring 基于 Plugin 插件开发(官方推荐)

Spring Boot 记录Controller接口请求日志7种方式,第六种性能极高

惊呆了!Controller接口返回值支持17种逆天类型

太神了!Spring Boot官方推荐模板引擎Mustache,简直强到离谱!

再见 Feign!Spring Boot + JSON-RPC远程调用新选择

优雅!自定义注解轻松管理多版本Controller接口

图片
图片
图片
图片
图片
图片
图片
图片
图片

【声明】内容源于网络
0
0
Spring全家桶实战案例
Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
内容 832
粉丝 0
Spring全家桶实战案例 Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
总阅读38
粉丝0
内容832