001/* 002 * Copyright 2002-2018 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 * <beans> 048 * 049 * <context:load-time-weaver/> 050 * 051 * <!-- application-specific <bean> definitions --> 052 * 053 * </beans> 054 * </pre> 055 * 056 * <h2>The {@code LoadTimeWeaverAware} interface</h2> 057 * Any bean that implements the {@link 058 * org.springframework.context.weaving.LoadTimeWeaverAware LoadTimeWeaverAware} interface 059 * will then receive the {@code LoadTimeWeaver} reference automatically; for example, 060 * Spring's JPA bootstrap support. 061 * 062 * <h2>Customizing the {@code LoadTimeWeaver}</h2> 063 * The default weaver is determined automatically: see {@link DefaultContextLoadTimeWeaver}. 064 * 065 * <p>To customize the weaver used, the {@code @Configuration} class annotated with 066 * {@code @EnableLoadTimeWeaving} may also implement the {@link LoadTimeWeavingConfigurer} 067 * interface and return a custom {@code LoadTimeWeaver} instance through the 068 * {@code #getLoadTimeWeaver} method: 069 * 070 * <pre class="code"> 071 * @Configuration 072 * @EnableLoadTimeWeaving 073 * public class AppConfig implements LoadTimeWeavingConfigurer { 074 * 075 * @Override 076 * public LoadTimeWeaver getLoadTimeWeaver() { 077 * MyLoadTimeWeaver ltw = new MyLoadTimeWeaver(); 078 * ltw.addClassTransformer(myClassFileTransformer); 079 * // ... 080 * return ltw; 081 * } 082 * }</pre> 083 * 084 * <p>The example above can be compared to the following Spring XML configuration: 085 * 086 * <pre class="code"> 087 * <beans> 088 * 089 * <context:load-time-weaver weaverClass="com.acme.MyLoadTimeWeaver"/> 090 * 091 * </beans> 092 * </pre> 093 * 094 * <p>The code example differs from the XML example in that it actually instantiates the 095 * {@code MyLoadTimeWeaver} type, meaning that it can also configure the instance, e.g. 096 * calling the {@code #addClassTransformer} method. This demonstrates how the code-based 097 * configuration approach is more flexible through direct programmatic access. 098 * 099 * <h2>Enabling AspectJ-based weaving</h2> 100 * AspectJ load-time weaving may be enabled with the {@link #aspectjWeaving()} 101 * attribute, which will cause the {@linkplain 102 * org.aspectj.weaver.loadtime.ClassPreProcessorAgentAdapter AspectJ class transformer} to 103 * be registered through {@link LoadTimeWeaver#addTransformer}. AspectJ weaving will be 104 * activated by default if a "META-INF/aop.xml" resource is present on the classpath. 105 * Example: 106 * 107 * <pre class="code"> 108 * @Configuration 109 * @EnableLoadTimeWeaving(aspectjWeaving=ENABLED) 110 * public class AppConfig { 111 * }</pre> 112 * 113 * <p>The example above can be compared to the following Spring XML configuration: 114 * 115 * <pre class="code"> 116 * <beans> 117 * 118 * <context:load-time-weaver aspectj-weaving="on"/> 119 * 120 * </beans> 121 * </pre> 122 * 123 * <p>The two examples are equivalent with one significant exception: in the XML case, 124 * the functionality of {@code <context:spring-configured>} is implicitly enabled when 125 * {@code aspectj-weaving} is "on". This does not occur when using 126 * {@code @EnableLoadTimeWeaving(aspectjWeaving=ENABLED)}. Instead you must explicitly add 127 * {@code @EnableSpringConfigured} (included in the {@code spring-aspects} module) 128 * 129 * @author Chris Beams 130 * @since 3.1 131 * @see LoadTimeWeaver 132 * @see DefaultContextLoadTimeWeaver 133 * @see org.aspectj.weaver.loadtime.ClassPreProcessorAgentAdapter 134 */ 135@Target(ElementType.TYPE) 136@Retention(RetentionPolicy.RUNTIME) 137@Documented 138@Import(LoadTimeWeavingConfiguration.class) 139public @interface EnableLoadTimeWeaving { 140 141 /** 142 * Whether AspectJ weaving should be enabled. 143 */ 144 AspectJWeaving aspectjWeaving() default AspectJWeaving.AUTODETECT; 145 146 147 /** 148 * AspectJ weaving enablement options. 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}