🎉🎉《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.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
public class CommonService {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
public class UserService {public void query() {System.err.println("查询用户信息...") ;}}
2.4 测试new创建CommonService
接下来,我们直接通过定义Runner进行测试,通过new创建CommonService后测试是否可以正确的注入UserService。
public class TestRunner implements CommandLineRunner {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文件,进行相关的配置,如下:
<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 增强,从而扩展功能。
新建切面
public class ProfilingAspect {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());}}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 乐观锁 + 悲观锁性能调优
告别OOM!Spring Boot 流式导出百万数据:支持MyBatis/JPA/Jdbc
强大!Spring Boot 动态JSON字段按需输出,一个注解搞定
Spring Boot API接口性能提升:10项核心优化技能全解析
优雅!Spring 基于 Plugin 插件开发(官方推荐)
Spring Boot 记录Controller接口请求日志7种方式,第六种性能极高
太神了!Spring Boot官方推荐模板引擎Mustache,简直强到离谱!
再见 Feign!Spring Boot + JSON-RPC远程调用新选择


