一、XML配置静态AOP load-time-weaver
1、BeanDefinition解析阶段自定义名称空间 load-time-weaver
1.1 注册LoadTimeWeaverBeanDefinitionParser
public class ContextNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
}
}
1.2 load-time-weaver标签注册为名称为loadTimeWeaver的Bean LoadTimeWeaverBeanDefinitionParser
private static final String DEFAULT_LOAD_TIME_WEAVER_CLASS_NAME =
"org.springframework.context.weaving.DefaultContextLoadTimeWeaver";
protected String getBeanClassName(Element element) {
if (element.hasAttribute(WEAVER_CLASS_ATTRIBUTE)) {
return element.getAttribute(WEAVER_CLASS_ATTRIBUTE);
}
return DEFAULT_LOAD_TIME_WEAVER_CLASS_NAME;
}
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) {
// String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
return ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME;
}
private static final String ASPECTJ_WEAVING_ATTRIBUTE = "aspectj-weaving";
public static final String ASPECTJ_WEAVING_ENABLER_BEAN_NAME =
"org.springframework.context.config.internalAspectJWeavingEnabler";
private static final String ASPECTJ_WEAVING_ENABLER_CLASS_NAME =
"org.springframework.context.weaving.AspectJWeavingEnabler";
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//
if (isAspectJWeavingEnabled(element.getAttribute(ASPECTJ_WEAVING_ATTRIBUTE), parserContext)) {
if (!parserContext.getRegistry().containsBeanDefinition(ASPECTJ_WEAVING_ENABLER_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ASPECTJ_WEAVING_ENABLER_CLASS_NAME);
parserContext.registerBeanComponent(
new BeanComponentDefinition(def, ASPECTJ_WEAVING_ENABLER_BEAN_NAME));
}
// 存在AnnotationBeanConfigurerAspect时注册为Bean
if (isBeanConfigurerAspectEnabled(parserContext.getReaderContext().getBeanClassLoader())) {
new SpringConfiguredBeanDefinitionParser().parse(element, parserContext);
}
}
}
// 是否开启AspectJ静态织入
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().getBeanClassLoader();
// String ASPECTJ_AOP_XML_RESOURCE = "META-INF/aop.xml";
return (cl != null && cl.getResource(AspectJWeavingEnabler.ASPECTJ_AOP_XML_RESOURCE) != null);
}
}
// 是否存在AnnotationBeanConfigurerAspect
protected boolean isBeanConfigurerAspectEnabled(@Nullable ClassLoader beanClassLoader) {
// String BEAN_CONFIGURER_ASPECT_CLASS_NAME =
"org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect";
return ClassUtils.isPresent(SpringConfiguredBeanDefinitionParser.BEAN_CONFIGURER_ASPECT_CLASS_NAME,
beanClassLoader);
}
1.3 注册AnnotationBeanConfigurerAspect-SpringConfiguredBeanDefinitionParser
class SpringConfiguredBeanDefinitionParser implements BeanDefinitionParser {
public static final String BEAN_CONFIGURER_ASPECT_BEAN_NAME =
"org.springframework.context.config.internalBeanConfigurerAspect";
static final String BEAN_CONFIGURER_ASPECT_CLASS_NAME =
"org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect";
// 注册AnnotationBeanConfigurerAspect,能够获取ApsectJ织入增强后的对象
public BeanDefinition parse(Element element, ParserContext parserContext) {
if (!parserContext.getRegistry().containsBeanDefinition(BEAN_CONFIGURER_ASPECT_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
def.setBeanClassName(BEAN_CONFIGURER_ASPECT_CLASS_NAME);
def.setFactoryMethodName("aspectOf");
def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
def.setSource(parserContext.extractSource(element));
parserContext.registerBeanComponent(new BeanComponentDefinition(def, BEAN_CONFIGURER_ASPECT_BEAN_NAME));
}
return null;
}
}
2、LoadTimeWeaverAwareProcessor
2.1 注册LoadTimeWeaverAwareProcessor
AbstractApplicationContext.prepareBeanFactory
// String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
2.2 Bean初始化前注入LoadTimeWeaver
LoadTimeWeaverAwareProcessor实现了BeanPostProcessor。
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;
}
3、AspectJWeavingEnabler
invokeBeanFactoryPostProcessors()执行BeanFactory后处理器,AspectJWeavingEnabler实现了BeanFactoryPostProcessor。
在执行postProcessBeanFactory时,作为bean的AspectJWeavingEnabler已经实例化,已经注入loadTimeWeaver为DefaultContextLoadTimeWeaver,由LoadTimeWeaverAwareProcessor注入的。
DefaultContextLoadTimeWeaver中会根据不同的应用环境(Tomcat、GlassFish、JBoss、WebSphere、WebLogic)创建相应的LoadTimeWeaver,因为不同的应用容器都实现了自己的类加载器,注册transformer的方式各有差异,默认环境中使用的类加载器是sun.misc.Launcher.AppClassLoader,
DefaultContextLoadTimeWeaver包装了实际的LoadTimeWeaver,是装饰器模式的应用,LoadTimeWeaver提供统一的接口屏蔽了不同类加载器注册transformer的差异,实现一致处理。这里实际创建了InstrumentationLoadTimeWeaver,最终调用了Instrumentation.addTransformer(),参数为通过委托模式包装过的AspectJ的ClassPreProcessorAgentAdapter。这就是通过Spring整合AspectJ的过程,至于具体的类加载阶段的处理则由AspectJ接管。
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
enableAspectJWeaving(this.loadTimeWeaver, this.beanClassLoader);
}
// 使用给定的{@link LoadTimeWeaver}启用AspectJ编织。
public static void enableAspectJWeaving(
@Nullable LoadTimeWeaver weaverToUse, @Nullable 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()));
}
// ClassFileTransformer装饰器,它禁止对AspectJ 类的处理,以避免潜在的LinkageErrors。
private static class AspectJClassBypassingClassFileTransformer implements ClassFileTransformer {
private final ClassFileTransformer delegate;
public AspectJClassBypassingClassFileTransformer(ClassFileTransformer delegate) {
this.delegate = delegate;
}
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
if (className.startsWith("org.aspectj") || className.startsWith("org/aspectj")) {
return classfileBuffer;
}
return this.delegate.transform(loader, className, classBeingRedefined, protectionDomain,
classfileBuffer);
}
}
二、注解配置AOP静态代理 EnableLoadTimeWeaving
2.1 LoadTimeWeavingConfiguration
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableLTW = AnnotationConfigUtils.attributesFor(importMetadata, EnableLoadTimeWeaving.class);
if (this.enableLTW == null) {
throw new IllegalArgumentException(
"@EnableLoadTimeWeaving is not present on importing class " + importMetadata.getClassName());
}
}
@Bean(name = ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public LoadTimeWeaver loadTimeWeaver() {
Assert.state(this.beanClassLoader != null, "No ClassLoader set");
LoadTimeWeaver loadTimeWeaver = null;
if (this.ltwConfigurer != null) {
// The user has provided a custom LoadTimeWeaver instance
loadTimeWeaver = this.ltwConfigurer.getLoadTimeWeaver();
}
if (loadTimeWeaver == null) {
// No custom LoadTimeWeaver provided -> fall back to the default
loadTimeWeaver = new DefaultContextLoadTimeWeaver(this.beanClassLoader);
}
if (this.enableLTW != null) {
AspectJWeaving aspectJWeaving = this.enableLTW.getEnum("aspectjWeaving");
switch (aspectJWeaving) {
case DISABLED:
// AJ weaving is disabled -> do nothing
break;
case AUTODETECT:
if (this.beanClassLoader.getResource(AspectJWeavingEnabler.ASPECTJ_AOP_XML_RESOURCE) == null) {
// No aop.xml present on the classpath -> treat as 'disabled'
break;
}
// aop.xml is present on the classpath -> enable
AspectJWeavingEnabler.enableAspectJWeaving(loadTimeWeaver, this.beanClassLoader);
break;
case ENABLED:
AspectJWeavingEnabler.enableAspectJWeaving(loadTimeWeaver, this.beanClassLoader);
break;
}
}
return loadTimeWeaver;
}