spring 源码探索-- 静态AOP代理
来源:互联网 发布:云计算发展与政策论坛 编辑:程序博客网 时间:2024/05/18 02:38
load-time weaving LTW 表示的是
在虚拟机载入字节码文件时动态植入AspectJ切面。 比动态代理效率更高
开关 <context:load-time-weaver />
创建AOP静态代理
使用instrumentation,其实就是一个简化版的aop。
应用小案例,计算一个方法的执行时间。
1. 使用jboss的javassist动态改变字节码文件
2. 在虚拟机实例instrumentation中添加transformer.Instrumentation.addTransformer(ClassFileTransformer former)
3. ClassFileTransformer 实现类里面 transform
方法改变字节码文件的内容,加入需要增强的功能。比如计算当前时间。
aop代理
- 解析自定义标签,注册LoadTimeWeaverBeanDefinitionParser,
和动态代理类似. 解析时,先调用
AbstractSingleBeanDefinitionParser
中的 parseInternal,会产生一个beanDefaultContextLoadTimeWeaver
,这个bean 实现了LoadTimeWeaver
LoadTimeWeaverBeanDefinitionParser
里面注册AspectJWeavingEnabler
,这个bean 实现了 BeanFactoryPostProcessor, BeanClassLoaderAware, LoadTimeWeaverAware, Ordered 各个接口都有作用
DefaultContextLoadTimeWeaver
实现了BeanClassLoaderAware,在bean初始化的时候,先调用invokeAwareMethods(ps:在postProcessBeforeInitialization方法前调用),会执行setBeanClassLoader
,将类DefaultContextLoadTimeWeaver中的loadTimeWeaver属性赋值为InstrumentationLoadTimeWeaver
this.loadTimeWeaver = new InstrumentationLoadTimeWeaver(classLoader);
上面的代码,实例化的过程中,也将instrumentation 这个虚拟机实例也初始化好了。后面可以直接使用这个来操作addTransformer方法了。
注册LoadTimeWeaverAwareProcessor
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof LoadTimeWeaverAware) { LoadTimeWeaver ltw = this.loadTimeWeaver; if (ltw == null) { Assert.state(this.beanFactory != null, "BeanFactory required if no LoadTimeWeaver explicitly specified"); ltw = this.beanFactory.getBean( ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME, LoadTimeWeaver.class); } ((LoadTimeWeaverAware) bean).setLoadTimeWeaver(ltw); } return bean; }
以上代码的功能是,将AspectJWeavingEnabler 中的LoadTimeWeaver 属性赋值为DefaultContextLoadTimeWeaver。
AspectJWeavingEnabler postProcessBeanFactory AspectJWeavingEnabler
,这个bean 实现了 BeanFactoryPostProcessor,会在所有bean解析结束后,调用postProcessBeanFactory
public static void enableAspectJWeaving(LoadTimeWeaver weaverToUse, ClassLoader beanClassLoader) { if (weaverToUse == null) { if (InstrumentationLoadTimeWeaver.isInstrumentationAvailable()) { weaverToUse = new InstrumentationLoadTimeWeaver(beanClassLoader); } else { throw new IllegalStateException("No LoadTimeWeaver available"); } } weaverToUse.addTransformer(new AspectJClassBypassingClassFileTransformer( new ClassPreProcessorAgentAdapter())); }
注册转换器
weaverToUse.addTransformer(new AspectJClassBypassingClassFileTransformer(new ClassPreProcessorAgentAdapter()));
此时,weaverToUse已经是DefaultContextLoadTimeWeaver,调用addTransformer方法,会再次调用类中的loadTimeWeaver,也就是前面已经赋值的InstrumentationLoadTimeWeaver对象,这个对象里面就有Instrumentation。
这行代码就是:把改变字节码文件的处理类加入到虚拟机实例Instrumentation中。
最终就是调用了
InstrumentationLoadTimeWeaver.addTransformer()
@Override public void addTransformer(ClassFileTransformer transformer) { Assert.notNull(transformer, "Transformer must not be null"); FilteringClassFileTransformer actualTransformer = new FilteringClassFileTransformer(transformer, this.classLoader); synchronized (this.transformers) { if (this.instrumentation == null) { throw new IllegalStateException( "Must start with Java agent to use InstrumentationLoadTimeWeaver. See Spring documentation."); } this.instrumentation.addTransformer(actualTransformer); this.transformers.add(actualTransformer); } }
最后,一旦把actualTransformer 加入到Instrumentation中,JVM进行类加载的时候,会在字节码文件中织入需要增强的代码,达到了静态aop代理的效果。
- spring 源码探索-- 静态AOP代理
- spring 源码探索 -- aop 标签解析和创建代理
- Spring AOP(1),静态代理
- 【spring 3】AOP:静态代理
- Spring(AOP静态代理)
- Spring AOP 静态代理与动态代理
- spring AOP 静态代理和动态代理
- Spring Aop源码学习--Aop代理AopProxy
- Spring AOP 学习之静态代理
- Spring模拟aop静态代理案例<一>
- spring-aop入门之静态代理模式
- spring aop学习5:jdk静态代理
- spring(AOP)静态代理、JDK动态代理、cglib实现代理
- Spring源码之创建AOP代理
- Spring源码之 AOP 代理流程
- spring源码-5-aop动态代理
- 动态代理和静态代理以及spring的aop
- jdk 静态代理、动态代理、cglib、spring AOP
- spring 源码探索 -- aop 标签解析和创建代理
- SSH框架之Hibernate的继承映射的形式一(一张表)
- LeetCode解题报告 344. Reverse String [easy]
- Genymotion模拟器安装教程
- 简单日历插件jquery.date_input.pack
- spring 源码探索-- 静态AOP代理
- 【CF 86D】Powerful array
- BOM
- 3925: [Zjoi2015]地震后的幻想乡
- Spring Framework 5.0.0.M3中文文档 翻译记录 Part I. Spring框架概览1-2.2
- LeetCode解题报告 383. Ransom Note [easy]
- omnipeek安装教程
- Git代码管理工具
- PHP配置xdebug