001/* 002 * Copyright 2002-2020 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.context.annotation; 018 019import org.springframework.beans.factory.BeanClassLoaderAware; 020import org.springframework.beans.factory.annotation.Autowired; 021import org.springframework.beans.factory.config.BeanDefinition; 022import org.springframework.context.ConfigurableApplicationContext; 023import org.springframework.context.annotation.EnableLoadTimeWeaving.AspectJWeaving; 024import org.springframework.context.weaving.AspectJWeavingEnabler; 025import org.springframework.context.weaving.DefaultContextLoadTimeWeaver; 026import org.springframework.core.annotation.AnnotationAttributes; 027import org.springframework.core.type.AnnotationMetadata; 028import org.springframework.instrument.classloading.LoadTimeWeaver; 029 030/** 031 * {@code @Configuration} class that registers a {@link LoadTimeWeaver} bean. 032 * 033 * <p>This configuration class is automatically imported when using the 034 * {@link EnableLoadTimeWeaving} annotation. See {@code @EnableLoadTimeWeaving} 035 * javadoc for complete usage details. 036 * 037 * @author Chris Beams 038 * @since 3.1 039 * @see LoadTimeWeavingConfigurer 040 * @see ConfigurableApplicationContext#LOAD_TIME_WEAVER_BEAN_NAME 041 */ 042@Configuration 043@Role(BeanDefinition.ROLE_INFRASTRUCTURE) 044public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoaderAware { 045 046 private AnnotationAttributes enableLTW; 047 048 private LoadTimeWeavingConfigurer ltwConfigurer; 049 050 private ClassLoader beanClassLoader; 051 052 053 @Override 054 public void setImportMetadata(AnnotationMetadata importMetadata) { 055 this.enableLTW = AnnotationConfigUtils.attributesFor(importMetadata, EnableLoadTimeWeaving.class); 056 if (this.enableLTW == null) { 057 throw new IllegalArgumentException( 058 "@EnableLoadTimeWeaving is not present on importing class " + importMetadata.getClassName()); 059 } 060 } 061 062 @Autowired(required = false) 063 public void setLoadTimeWeavingConfigurer(LoadTimeWeavingConfigurer ltwConfigurer) { 064 this.ltwConfigurer = ltwConfigurer; 065 } 066 067 @Override 068 public void setBeanClassLoader(ClassLoader beanClassLoader) { 069 this.beanClassLoader = beanClassLoader; 070 } 071 072 073 @Bean(name = ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME) 074 @Role(BeanDefinition.ROLE_INFRASTRUCTURE) 075 public LoadTimeWeaver loadTimeWeaver() { 076 LoadTimeWeaver loadTimeWeaver = null; 077 078 if (this.ltwConfigurer != null) { 079 // The user has provided a custom LoadTimeWeaver instance 080 loadTimeWeaver = this.ltwConfigurer.getLoadTimeWeaver(); 081 } 082 083 if (loadTimeWeaver == null) { 084 // No custom LoadTimeWeaver provided -> fall back to the default 085 loadTimeWeaver = new DefaultContextLoadTimeWeaver(this.beanClassLoader); 086 } 087 088 AspectJWeaving aspectJWeaving = this.enableLTW.getEnum("aspectjWeaving"); 089 switch (aspectJWeaving) { 090 case DISABLED: 091 // AJ weaving is disabled -> do nothing 092 break; 093 case AUTODETECT: 094 if (this.beanClassLoader.getResource(AspectJWeavingEnabler.ASPECTJ_AOP_XML_RESOURCE) == null) { 095 // No aop.xml present on the classpath -> treat as 'disabled' 096 break; 097 } 098 // aop.xml is present on the classpath -> enable 099 AspectJWeavingEnabler.enableAspectJWeaving(loadTimeWeaver, this.beanClassLoader); 100 break; 101 case ENABLED: 102 AspectJWeavingEnabler.enableAspectJWeaving(loadTimeWeaver, this.beanClassLoader); 103 break; 104 } 105 106 return loadTimeWeaver; 107 } 108 109}