1 /* 2 * Copyright 2002-2012 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.springframework.context.annotation; 18 19 import java.util.LinkedHashSet; 20 import java.util.Set; 21 22 import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; 23 import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor; 24 import org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor; 25 import org.springframework.beans.factory.config.BeanDefinition; 26 import org.springframework.beans.factory.config.BeanDefinitionHolder; 27 import org.springframework.beans.factory.support.AbstractBeanDefinition; 28 import org.springframework.beans.factory.support.BeanDefinitionRegistry; 29 import org.springframework.beans.factory.support.RootBeanDefinition; 30 import org.springframework.core.type.AnnotationMetadata; 31 import org.springframework.util.ClassUtils; 32 33 import static org.springframework.context.annotation.MetadataUtils.*; 34 35 /** 36 * Utility class that allows for convenient registration of common 37 * {@link org.springframework.beans.factory.config.BeanPostProcessor} and 38 * {@link org.springframework.beans.factory.config.BeanFactoryPostProcessor} 39 * definitions for annotation-based configuration. 40 * 41 * @author Mark Fisher 42 * @author Juergen Hoeller 43 * @author Chris Beams 44 * @since 2.5 45 * @see CommonAnnotationBeanPostProcessor 46 * @see org.springframework.context.annotation.ConfigurationClassPostProcessor 47 * @see org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor 48 * @see org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor 49 * @see org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor 50 */ 51 public class AnnotationConfigUtils { 52 53 /** 54 * The bean name of the internally managed Configuration annotation processor. 55 */ 56 public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME = 57 "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"; 58 59 /** 60 * The bean name of the internally managed BeanNameGenerator for use when processing 61 * {@link Configuration} classes. Set by {@link AnnotationConfigApplicationContext} 62 * and {@code AnnotationConfigWebApplicationContext} during bootstrap in order to make 63 * any custom name generation strategy available to the underlying 64 * {@link ConfigurationClassPostProcessor}. 65 * @since 3.1.1 66 */ 67 public static final String CONFIGURATION_BEAN_NAME_GENERATOR = 68 "org.springframework.context.annotation.internalConfigurationBeanNameGenerator"; 69 70 /** 71 * The bean name of the internally managed Autowired annotation processor. 72 */ 73 public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME = 74 "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"; 75 76 /** 77 * The bean name of the internally managed Required annotation processor. 78 */ 79 public static final String REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME = 80 "org.springframework.context.annotation.internalRequiredAnnotationProcessor"; 81 82 /** 83 * The bean name of the internally managed JSR-250 annotation processor. 84 */ 85 public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME = 86 "org.springframework.context.annotation.internalCommonAnnotationProcessor"; 87 88 /** 89 * The bean name of the internally managed Scheduled annotation processor. 90 */ 91 public static final String SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME = 92 "org.springframework.context.annotation.internalScheduledAnnotationProcessor"; 93 94 /** 95 * The bean name of the internally managed Async annotation processor. 96 */ 97 public static final String ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME = 98 "org.springframework.context.annotation.internalAsyncAnnotationProcessor"; 99 100 /** 101 * The bean name of the internally managed AspectJ async execution aspect. 102 */ 103 public static final String ASYNC_EXECUTION_ASPECT_BEAN_NAME = 104 "org.springframework.scheduling.config.internalAsyncExecutionAspect"; 105 106 /** 107 * The class name of the AspectJ async execution aspect. 108 */ 109 public static final String ASYNC_EXECUTION_ASPECT_CLASS_NAME = 110 "org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect"; 111 112 /** 113 * The name of the AspectJ async execution aspect @{@code Configuration} class. 114 */ 115 public static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME = 116 "org.springframework.scheduling.aspectj.AspectJAsyncConfiguration"; 117 118 /** 119 * The bean name of the internally managed cache advisor. 120 */ 121 public static final String CACHE_ADVISOR_BEAN_NAME = 122 "org.springframework.cache.config.internalCacheAdvisor"; 123 124 /** 125 * The bean name of the internally managed cache aspect. 126 */ 127 public static final String CACHE_ASPECT_BEAN_NAME = 128 "org.springframework.cache.config.internalCacheAspect"; 129 130 /** 131 * The class name of the AspectJ caching aspect. 132 */ 133 public static final String CACHE_ASPECT_CLASS_NAME = 134 "org.springframework.cache.aspectj.AnnotationCacheAspect"; 135 136 /** 137 * The name of the AspectJ caching aspect @{@code Configuration} class. 138 */ 139 public static final String CACHE_ASPECT_CONFIGURATION_CLASS_NAME = 140 "org.springframework.cache.aspectj.AspectJCachingConfiguration"; 141 142 /** 143 * The bean name of the internally managed JPA annotation processor. 144 */ 145 public static final String PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME = 146 "org.springframework.context.annotation.internalPersistenceAnnotationProcessor"; 147 148 149 private static final String PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME = 150 "org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"; 151 152 153 private static final boolean jsr250Present = 154 ClassUtils.isPresent("javax.annotation.Resource", AnnotationConfigUtils.class.getClassLoader()); 155 156 private static final boolean jpaPresent = 157 ClassUtils.isPresent("javax.persistence.EntityManagerFactory", AnnotationConfigUtils.class.getClassLoader()) && 158 ClassUtils.isPresent(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, AnnotationConfigUtils.class.getClassLoader()); 159 160 161 /** 162 * Register all relevant annotation post processors in the given registry. 163 * @param registry the registry to operate on 164 */ registerAnnotationConfigProcessors(BeanDefinitionRegistry registry)165 public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) { 166 registerAnnotationConfigProcessors(registry, null); 167 } 168 169 /** 170 * Register all relevant annotation post processors in the given registry. 171 * @param registry the registry to operate on 172 * @param source the configuration source element (already extracted) 173 * that this registration was triggered from. May be <code>null</code>. 174 * @return a Set of BeanDefinitionHolders, containing all bean definitions 175 * that have actually been registered by this call 176 */ registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, Object source)177 public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( 178 BeanDefinitionRegistry registry, Object source) { 179 180 Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4); 181 182 if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { 183 RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); 184 def.setSource(source); 185 beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); 186 } 187 188 if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { 189 RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); 190 def.setSource(source); 191 beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); 192 } 193 194 if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { 195 RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class); 196 def.setSource(source); 197 beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); 198 } 199 200 // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. 201 if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { 202 RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); 203 def.setSource(source); 204 beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); 205 } 206 207 // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor. 208 if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { 209 RootBeanDefinition def = new RootBeanDefinition(); 210 try { 211 ClassLoader cl = AnnotationConfigUtils.class.getClassLoader(); 212 def.setBeanClass(cl.loadClass(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME)); 213 } 214 catch (ClassNotFoundException ex) { 215 throw new IllegalStateException( 216 "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); 217 } 218 def.setSource(source); 219 beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); 220 } 221 222 return beanDefs; 223 } 224 registerPostProcessor( BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName)225 private static BeanDefinitionHolder registerPostProcessor( 226 BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) { 227 228 definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); 229 registry.registerBeanDefinition(beanName, definition); 230 return new BeanDefinitionHolder(definition, beanName); 231 } 232 processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd)233 static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) { 234 AnnotationMetadata metadata = abd.getMetadata(); 235 if (metadata.isAnnotated(Primary.class.getName())) { 236 abd.setPrimary(true); 237 } 238 if (metadata.isAnnotated(Lazy.class.getName())) { 239 abd.setLazyInit(attributesFor(metadata, Lazy.class).getBoolean("value")); 240 } 241 if (metadata.isAnnotated(DependsOn.class.getName())) { 242 abd.setDependsOn(attributesFor(metadata, DependsOn.class).getStringArray("value")); 243 } 244 if (abd instanceof AbstractBeanDefinition) { 245 if (metadata.isAnnotated(Role.class.getName())) { 246 Integer role = attributesFor(metadata, Role.class).getNumber("value"); 247 ((AbstractBeanDefinition)abd).setRole(role); 248 } 249 } 250 } 251 applyScopedProxyMode( ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry)252 static BeanDefinitionHolder applyScopedProxyMode( 253 ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) { 254 255 ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode(); 256 if (scopedProxyMode.equals(ScopedProxyMode.NO)) { 257 return definition; 258 } 259 boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS); 260 return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass); 261 } 262 263 264 } 265