Spring LoadTimeWeaver 详解

7 篇文章 0 订阅
3 篇文章 0 订阅
 spring load time weaver 主要通过以下步骤完成 : 

   1. 在启动程序的 jvm argument 中增加 spring-agent.jar 以获得 jvm 导出的 instrumentation 
   2. aspectj 拦截 domain object 的创建 

   3. 在 AnnotationBeanConfigurerAspect 中完成对 domain object 的注入 

1. Add spring-agent.jar to jvm argument 
   
   如果是命令行启动, 使用 java -javaagent:#{your path}/spring-agent.jar MyProgram 命令启动程序, 如果是 ide, 在 jvm argument 中增加 -javaagent:#{your path}/spring-agent.jar 即可. 

   增加这个参数的目的就是获取 jvm 导出的 instrumentation 引用以便后续操作的进行, 打开 spring-agent.jar 的 META-INF/MENIFEST.MF 会发现其中一句 : Premain-Class: org.springframework.instrument.InstrumentationSavingAgent, 没错, 根据 instrumentation 规范, Premain-Class 就是用于处理 instrumentation 的入口, 事实上 spring-agent.jar 里也只有这一个 class, 打开代码会发现非常简单 : 

public class InstrumentationSavingAgent {

	private static volatile Instrumentation instrumentation;


	/**
	 * Save the {@link Instrumentation} interface exposed by the JVM.
	 */
	public static void premain(String agentArgs, Instrumentation inst) {
		instrumentation = inst;
	}

}

在 premain 方法里将 instrumentation 保存到 static 引用中以便后续访问.

2. 配置 spring 支持 load time weaver 

	protected boolean isAspectJWeavingEnabled(String value, ParserContext parserContext) {
		if ("on".equals(value)) {
			return true;
		}
		else if ("off".equals(value)) {
			return false;
		}
		else {
			// Determine default...
			ClassLoader cl = parserContext.getReaderContext().getResourceLoader().getClassLoader();
			return (cl.getResource(ASPECTJ_AOP_XML_RESOURCE) != null);
		}
	}

@Configurable(autowire = Autowire.BY_TYPE)  
public class User {  
      
    @Resource  
    // 或使用 @Autowired  
    private UserRepository userRepository;  
      
    public void save() {  
        userRepository.save(this);  
    }  
  
}  

4. 将 spring-agent.jar, spring-aspects.jar, aspectj-weaver.jar, aspectj-rt.jar 加入到 classpath 中, 运行期主要发生以下调用 :  

  • LoadTimeWeaverBeanDefinitionParser (spring.jar) // 解析配置
  • ->  AspectJWeavingEnabler (spring.jar) // 开启 aspectj weaving
  • ->  InstrumentationSavingAgent (spring-agent.jar)  // 获取 instrumentation
  • ->  InstrumentationLoadTimeWeaver#addTransformer (spring.jar) // 增加 aspectj class transformer 到 instrumentation
  • ->  ClassPreProcessorAgentAdapter#transform (aspectj-weaver.jar) // aspectj 拦截 domain object 装载
  • ->  AnnotationBeanConfigurerAspect#configureBean (spring-aspects.jar) // spring 注入依赖到标注了 @Configurable 的对象中
至此完成整个 load time weave 过程. 
注意前文中的 <context:annotation-config /> 并不是必须的, 如果不配置, userRepository 就不能用 annotation(@Resource 或 @Autowired) 注入而必须使用 set 方法. 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring是一个轻量级的、非侵入式的IOC和AOP的一站式的Java开发框架。它于2003年兴起,旨在简化企业级应用开发。Spring的核心功能的jar包大小较小,不需要业务代码继承或实现Spring中的任何类或接口。Spring通过控制反转(IOC)将对象的创建权交给框架,而面向切面编程(AOP)是一种编程思想,是面向对象编程(OOP)的一种补充。Spring还提供了数据访问功能和Web功能,并可以很好地管理其他框架。\[2\] 在Spring中,可以使用注解来描述Bean,其中@Repository是一个泛化的概念,表示一个组件(Bean),可以应用在任何层次。只需将该注解标注在相应的类上即可。\[3\] 总之,Spring是一个功能强大的框架,提供了IOC和AOP的支持,可以简化企业级应用开发,并且具有灵活的注解机制来描述Bean。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [Spring详解(超全面)](https://blog.csdn.net/ailaohuyou211/article/details/130394148)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [spring超全面详解](https://blog.csdn.net/weixin_71243923/article/details/128267166)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值