001/* 002 * Copyright 2002-2016 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 java.lang.annotation.Documented; 020import java.lang.annotation.ElementType; 021import java.lang.annotation.Retention; 022import java.lang.annotation.RetentionPolicy; 023import java.lang.annotation.Target; 024 025import org.springframework.context.weaving.DefaultContextLoadTimeWeaver; 026import org.springframework.instrument.classloading.LoadTimeWeaver; 027 028/** 029 * Activates a Spring {@link LoadTimeWeaver} for this application context, available as 030 * a bean with the name "loadTimeWeaver", similar to the {@code <context:load-time-weaver>} 031 * element in Spring XML. 032 * 033 * <p>To be used on @{@link org.springframework.context.annotation.Configuration Configuration} classes; 034 * the simplest possible example of which follows: 035 * 036 * <pre class="code"> 037 * @Configuration 038 * @EnableLoadTimeWeaving 039 * public class AppConfig { 040 * 041 * // application-specific @Bean definitions ... 042 * }</pre> 043 * 044 * The example above is equivalent to the following Spring XML configuration: 045 * 046 * <pre class="code"> 047 * {@code 048 * <beans> 049 * 050 * <context:load-time-weaver/> 051 * 052 * <!-- application-specific <bean> definitions --> 053 * 054 * </beans> 055 * }</pre> 056 * 057 * <h2>The {@code LoadTimeWeaverAware} interface</h2> 058 * Any bean that implements the {@link 059 * org.springframework.context.weaving.LoadTimeWeaverAware LoadTimeWeaverAware} interface 060 * will then receive the {@code LoadTimeWeaver} reference automatically; for example, 061 * Spring's JPA bootstrap support. 062 * 063 * <h2>Customizing the {@code LoadTimeWeaver}</h2> 064 * The default weaver is determined automatically: see {@link DefaultContextLoadTimeWeaver}. 065 * 066 * <p>To customize the weaver used, the {@code @Configuration} class annotated with 067 * {@code @EnableLoadTimeWeaving} may also implement the {@link LoadTimeWeavingConfigurer} 068 * interface and return a custom {@code LoadTimeWeaver} instance through the 069 * {@code #getLoadTimeWeaver} method: 070 * 071 * <pre class="code"> 072 * @Configuration 073 * @EnableLoadTimeWeaving 074 * public class AppConfig implements LoadTimeWeavingConfigurer { 075 * 076 * @Override 077 * public LoadTimeWeaver getLoadTimeWeaver() { 078 * MyLoadTimeWeaver ltw = new MyLoadTimeWeaver(); 079 * ltw.addClassTransformer(myClassFileTransformer); 080 * // ... 081 * return ltw; 082 * } 083 * }</pre> 084 * 085 * <p>The example above can be compared to the following Spring XML configuration: 086 * 087 * <pre class="code"> 088 * {@code 089 * <beans> 090 * 091 * <context:load-time-weaver weaverClass="com.acme.MyLoadTimeWeaver"/> 092 * 093 * </beans> 094 * }</pre> 095 * 096 * <p>The code example differs from the XML example in that it actually instantiates the 097 * {@code MyLoadTimeWeaver} type, meaning that it can also configure the instance, e.g. 098 * calling the {@code #addClassTransformer} method. This demonstrates how the code-based 099 * configuration approach is more flexible through direct programmatic access. 100 * 101 * <h2>Enabling AspectJ-based weaving</h2> 102 * AspectJ load-time weaving may be enabled with the {@link #aspectjWeaving()} 103 * attribute, which will cause the {@linkplain 104 * org.aspectj.weaver.loadtime.ClassPreProcessorAgentAdapter AspectJ class transformer} to 105 * be registered through {@link LoadTimeWeaver#addTransformer}. AspectJ weaving will be 106 * activated by default if a "META-INF/aop.xml" resource is present on the classpath. 107 * Example: 108 * 109 * <pre class="code"> 110 * @Configuration 111 * @EnableLoadTimeWeaving(aspectjWeaving=ENABLED) 112 * public class AppConfig { 113 * }</pre> 114 * 115 * <p>The example above can be compared to the following Spring XML configuration: 116 * 117 * <pre class="code"> 118 * {@code 119 * <beans> 120 * 121 * <context:load-time-weaver aspectj-weaving="on"/> 122 * 123 * </beans> 124 * }</pre> 125 * 126 * <p>The two examples are equivalent with one significant exception: in the XML case, 127 * the functionality of {@code <context:spring-configured>} is implicitly enabled when 128 * {@code aspectj-weaving} is "on". This does not occur when using 129 * {@code @EnableLoadTimeWeaving(aspectjWeaving=ENABLED)}. Instead you must explicitly add 130 * {@code @EnableSpringConfigured} (included in the {@code spring-aspects} module) 131 * 132 * @author Chris Beams 133 * @since 3.1 134 * @see LoadTimeWeaver 135 * @see DefaultContextLoadTimeWeaver 136 * @see org.aspectj.weaver.loadtime.ClassPreProcessorAgentAdapter 137 */ 138@Target(ElementType.TYPE) 139@Retention(RetentionPolicy.RUNTIME) 140@Documented 141@Import(LoadTimeWeavingConfiguration.class) 142public @interface EnableLoadTimeWeaving { 143 144 /** 145 * Whether AspectJ weaving should be enabled. 146 */ 147 AspectJWeaving aspectjWeaving() default AspectJWeaving.AUTODETECT; 148 149 150 enum AspectJWeaving { 151 152 /** 153 * Switches on Spring-based AspectJ load-time weaving. 154 */ 155 ENABLED, 156 157 /** 158 * Switches off Spring-based AspectJ load-time weaving (even if a 159 * "META-INF/aop.xml" resource is present on the classpath). 160 */ 161 DISABLED, 162 163 /** 164 * Switches on AspectJ load-time weaving if a "META-INF/aop.xml" resource 165 * is present in the classpath. If there is no such resource, then AspectJ 166 * load-time weaving will be switched off. 167 */ 168 AUTODETECT; 169 } 170 171}