diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AdviceModeImportSelector.java b/spring-context/src/main/java/org/springframework/context/annotation/AdviceModeImportSelector.java index 826214448b4..dc34ab59a96 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AdviceModeImportSelector.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AdviceModeImportSelector.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,16 +23,12 @@ import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; import org.springframework.util.Assert; -import static org.springframework.context.annotation.MetadataUtils.*; - -/** + /** * Convenient base class for {@link ImportSelector} implementations that select imports * based on an {@link AdviceMode} value from an annotation (such as the {@code @Enable*} * annotations). * - * @param Annotation containing {@linkplain #getAdviceModeAttributeName() AdviceMode - * attribute} - * + * @param Annotation containing {@linkplain #getAdviceModeAttributeName() AdviceMode attribute} * @author Chris Beams * @since 3.1 */ @@ -40,6 +36,7 @@ public abstract class AdviceModeImportSelector implements public static final String DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME = "mode"; + /** * The name of the {@link AdviceMode} attribute for the annotation specified by the * generic type {@code A}. The default is {@value #DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME}, @@ -50,17 +47,13 @@ public abstract class AdviceModeImportSelector implements } /** - * {@inheritDoc} - * - *

This implementation resolves the type of annotation from generic metadata and + * This implementation resolves the type of annotation from generic metadata and * validates that (a) the annotation is in fact present on the importing * {@code @Configuration} class and (b) that the given annotation has an * {@linkplain #getAdviceModeAttributeName() advice mode attribute} of type * {@link AdviceMode}. - * *

The {@link #selectImports(AdviceMode)} method is then invoked, allowing the * concrete implementation to choose imports in a safe and convenient fashion. - * * @throws IllegalArgumentException if expected annotation {@code A} is not present * on the importing {@code @Configuration} class or if {@link #selectImports(AdviceMode)} * returns {@code null} @@ -68,30 +61,24 @@ public abstract class AdviceModeImportSelector implements @Override public final String[] selectImports(AnnotationMetadata importingClassMetadata) { Class annoType = GenericTypeResolver.resolveTypeArgument(this.getClass(), AdviceModeImportSelector.class); - - AnnotationAttributes attributes = attributesFor(importingClassMetadata, annoType); + AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType); Assert.notNull(attributes, String.format( "@%s is not present on importing class '%s' as expected", annoType.getSimpleName(), importingClassMetadata.getClassName())); AdviceMode adviceMode = attributes.getEnum(this.getAdviceModeAttributeName()); - String[] imports = selectImports(adviceMode); Assert.notNull(imports, String.format("Unknown AdviceMode: '%s'", adviceMode)); - return imports; } /** * Determine which classes should be imported based on the given {@code AdviceMode}. - * *

Returning {@code null} from this method indicates that the {@code AdviceMode} could * not be handled or was unknown and that an {@code IllegalArgumentException} should * be thrown. - * * @param adviceMode the value of the {@linkplain #getAdviceModeAttributeName() * advice mode attribute} for the annotation specified via generics. - * * @return array containing classes to import; empty array if none, {@code null} if * the given {@code AdviceMode} is unknown. */ diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java index 89ac1c8c276..3dad0dd2e82 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java @@ -87,7 +87,7 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator { Set types = amd.getAnnotationTypes(); String beanName = null; for (String type : types) { - AnnotationAttributes attributes = MetadataUtils.attributesFor(amd, type); + AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type); if (isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) { String value = (String) attributes.get("value"); if (StringUtils.hasLength(value)) { diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java index f283bb6d2c0..1457fa7bbcf 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,11 +27,10 @@ import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.core.type.AnnotationMetadata; +import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.type.AnnotatedTypeMetadata; import org.springframework.util.ClassUtils; -import static org.springframework.context.annotation.MetadataUtils.*; - /** * Utility class that allows for convenient registration of common * {@link org.springframework.beans.factory.config.BeanPostProcessor} and @@ -231,20 +230,31 @@ public class AnnotationConfigUtils { } static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) { - AnnotationMetadata metadata = abd.getMetadata(); - if (metadata.isAnnotated(Primary.class.getName())) { - abd.setPrimary(true); - } + processCommonDefinitionAnnotations(abd, abd.getMetadata()); + } + + static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) { if (metadata.isAnnotated(Lazy.class.getName())) { abd.setLazyInit(attributesFor(metadata, Lazy.class).getBoolean("value")); } + else if (abd.getMetadata().isAnnotated(Lazy.class.getName())) { + abd.setLazyInit(attributesFor(abd.getMetadata(), Lazy.class).getBoolean("value")); + } + + if (metadata.isAnnotated(Primary.class.getName())) { + abd.setPrimary(true); + } if (metadata.isAnnotated(DependsOn.class.getName())) { abd.setDependsOn(attributesFor(metadata, DependsOn.class).getStringArray("value")); } + if (abd instanceof AbstractBeanDefinition) { + AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd; if (metadata.isAnnotated(Role.class.getName())) { - Integer role = attributesFor(metadata, Role.class).getNumber("value"); - ((AbstractBeanDefinition)abd).setRole(role); + absBd.setRole(attributesFor(metadata, Role.class).getNumber("value").intValue()); + } + if (metadata.isAnnotated(Description.class.getName())) { + absBd.setDescription(attributesFor(metadata, Description.class).getString("value")); } } } @@ -260,5 +270,12 @@ public class AnnotationConfigUtils { return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass); } + static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, Class annoClass) { + return attributesFor(metadata, annoClass.getName()); + } + + static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, String annoClassName) { + return AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(annoClassName, false)); + } } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationScopeMetadataResolver.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationScopeMetadataResolver.java index 878638b68b7..5d4ce9c9522 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationScopeMetadataResolver.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationScopeMetadataResolver.java @@ -77,7 +77,7 @@ public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver { ScopeMetadata metadata = new ScopeMetadata(); if (definition instanceof AnnotatedBeanDefinition) { AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition; - AnnotationAttributes attributes = MetadataUtils.attributesFor(annDef.getMetadata(), this.scopeAnnotationType); + AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(annDef.getMetadata(), this.scopeAnnotationType); if (attributes != null) { metadata.setScopeName(attributes.getString("value")); ScopedProxyMode proxyMode = attributes.getEnum("proxyMode"); diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AspectJAutoProxyRegistrar.java b/spring-context/src/main/java/org/springframework/context/annotation/AspectJAutoProxyRegistrar.java index 5b3c522d8fb..c73fcc7a2d0 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AspectJAutoProxyRegistrar.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AspectJAutoProxyRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,16 +21,14 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; -import static org.springframework.context.annotation.MetadataUtils.*; - /** * Registers an {@link org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator * AnnotationAwareAspectJAutoProxyCreator} against the current {@link BeanDefinitionRegistry} * as appropriate based on a given @{@link EnableAspectJAutoProxy} annotation. * * @author Chris Beams - * @see EnableAspectJAutoProxy * @since 3.1 + * @see EnableAspectJAutoProxy */ class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @@ -46,7 +44,7 @@ class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); AnnotationAttributes enableAJAutoProxy = - attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); + AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); if (enableAJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AutoProxyRegistrar.java b/spring-context/src/main/java/org/springframework/context/annotation/AutoProxyRegistrar.java index e0fde7df8fd..88232782f24 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AutoProxyRegistrar.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AutoProxyRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,6 @@ package org.springframework.context.annotation; -import static org.springframework.context.annotation.MetadataUtils.attributesFor; - import java.util.Set; import org.apache.commons.logging.Log; @@ -61,7 +59,7 @@ public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar { boolean candidateFound = false; Set annoTypes = importingClassMetadata.getAnnotationTypes(); for (String annoType : annoTypes) { - AnnotationAttributes candidate = attributesFor(importingClassMetadata, annoType); + AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType); Object mode = candidate.get("mode"); Object proxyTargetClass = candidate.get("proxyTargetClass"); if (mode != null && proxyTargetClass != null diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java index 4aa586dd2c3..291c68cbc0d 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java @@ -53,8 +53,6 @@ import org.springframework.core.type.MethodMetadata; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.util.StringUtils; -import static org.springframework.context.annotation.MetadataUtils.*; - /** * Reads a given fully-populated set of ConfigurationClass instances, registering bean * definitions with the given {@link BeanDefinitionRegistry} based on its contents. @@ -178,14 +176,13 @@ class ConfigurationClassBeanDefinitionReader { * with the BeanDefinitionRegistry based on its contents. */ private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) { - if (conditionEvaluator.shouldSkip(beanMethod.getMetadata(), - ConfigurationPhase.REGISTER_BEAN)) { + if (this.conditionEvaluator.shouldSkip(beanMethod.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { return; } ConfigurationClass configClass = beanMethod.getConfigurationClass(); MethodMetadata metadata = beanMethod.getMetadata(); - RootBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass); + ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass); beanDef.setResource(configClass.getResource()); beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource())); if (metadata.isStatic()) { @@ -201,14 +198,8 @@ class ConfigurationClassBeanDefinitionReader { beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE); - // consider role - AnnotationAttributes role = attributesFor(metadata, Role.class); - if (role != null) { - beanDef.setRole(role.getNumber("value")); - } - // consider name and any aliases - AnnotationAttributes bean = attributesFor(metadata, Bean.class); + AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class); List names = new ArrayList(Arrays.asList(bean.getStringArray("name"))); String beanName = (names.size() > 0 ? names.remove(0) : beanMethod.getMetadata().getMethodName()); for (String alias : names) { @@ -230,27 +221,7 @@ class ConfigurationClassBeanDefinitionReader { } } - if (metadata.isAnnotated(Primary.class.getName())) { - beanDef.setPrimary(true); - } - - // is this bean to be instantiated lazily? - if (metadata.isAnnotated(Lazy.class.getName())) { - AnnotationAttributes lazy = attributesFor(metadata, Lazy.class); - beanDef.setLazyInit(lazy.getBoolean("value")); - } - else if (configClass.getMetadata().isAnnotated(Lazy.class.getName())){ - AnnotationAttributes lazy = attributesFor(configClass.getMetadata(), Lazy.class); - beanDef.setLazyInit(lazy.getBoolean("value")); - } - - if (metadata.isAnnotated(DependsOn.class.getName())) { - AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class); - String[] otherBeans = dependsOn.getStringArray("value"); - if (otherBeans.length > 0) { - beanDef.setDependsOn(otherBeans); - } - } + AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata); Autowire autowire = bean.getEnum("autowire"); if (autowire.isAutowire()) { @@ -269,7 +240,7 @@ class ConfigurationClassBeanDefinitionReader { // consider scoping ScopedProxyMode proxyMode = ScopedProxyMode.NO; - AnnotationAttributes scope = attributesFor(metadata, Scope.class); + AnnotationAttributes scope = AnnotationConfigUtils.attributesFor(metadata, Scope.class); if (scope != null) { beanDef.setScope(scope.getString("value")); proxyMode = scope.getEnum("proxyMode"); diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java index 8b03db8e54d..f2550993bfb 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java @@ -66,8 +66,6 @@ import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.filter.AssignableTypeFilter; import org.springframework.util.StringUtils; -import static org.springframework.context.annotation.MetadataUtils.*; - /** * Parses a {@link Configuration} class definition, populating a collection of * {@link ConfigurationClass} objects (parsing a single Configuration class may result in @@ -223,13 +221,13 @@ class ConfigurationClassParser { processMemberClasses(configClass, sourceClass); // process any @PropertySource annotations - AnnotationAttributes propertySource = attributesFor(sourceClass.getMetadata(), org.springframework.context.annotation.PropertySource.class); + AnnotationAttributes propertySource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), org.springframework.context.annotation.PropertySource.class); if (propertySource != null) { processPropertySource(propertySource); } // process any @ComponentScan annotations - AnnotationAttributes componentScan = attributesFor(sourceClass.getMetadata(), ComponentScan.class); + AnnotationAttributes componentScan = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ComponentScan.class); if (componentScan != null) { // the config class is annotated with @ComponentScan -> perform the scan immediately if (!conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { @@ -250,7 +248,7 @@ class ConfigurationClassParser { // process any @ImportResource annotations if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) { - AnnotationAttributes importResource = attributesFor(sourceClass.getMetadata(), ImportResource.class); + AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class); String[] resources = importResource.getStringArray("value"); Class readerClass = importResource.getClass("reader"); for (String resource : resources) { diff --git a/spring-context/src/main/java/org/springframework/context/annotation/Description.java b/spring-context/src/main/java/org/springframework/context/annotation/Description.java new file mode 100644 index 00000000000..059da3caa2f --- /dev/null +++ b/spring-context/src/main/java/org/springframework/context/annotation/Description.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Adds a textual description to bean definitions derived from + * {@link org.springframework.stereotype.Component} or {@link Bean}. + * + * @author Juergen Hoeller + * @since 4.0 + * @see org.springframework.beans.factory.config.BeanDefinition#getDescription() + */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Description { + + /** + * The textual description to associate with the bean definition. + */ + String value(); + +} diff --git a/spring-context/src/main/java/org/springframework/context/annotation/LoadTimeWeavingConfiguration.java b/spring-context/src/main/java/org/springframework/context/annotation/LoadTimeWeavingConfiguration.java index efc2a0e30e4..218fbe75cab 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/LoadTimeWeavingConfiguration.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/LoadTimeWeavingConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,9 +33,9 @@ import static org.springframework.context.weaving.AspectJWeavingEnabler.*; /** * {@code @Configuration} class that registers a {@link LoadTimeWeaver} bean. * - *

This configuration class is automatically imported when using the @{@link - * EnableLoadTimeWeaving} annotation. See {@code @EnableLoadTimeWeaving} Javadoc for - * complete usage details. + *

This configuration class is automatically imported when using the + * @{@link EnableLoadTimeWeaving} annotation. See {@code @EnableLoadTimeWeaving} + * javadoc for complete usage details. * * @author Chris Beams * @since 3.1 @@ -52,12 +52,12 @@ public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoade private ClassLoader beanClassLoader; + @Override public void setImportMetadata(AnnotationMetadata importMetadata) { - this.enableLTW = MetadataUtils.attributesFor(importMetadata, EnableLoadTimeWeaving.class); + this.enableLTW = AnnotationConfigUtils.attributesFor(importMetadata, EnableLoadTimeWeaving.class); Assert.notNull(this.enableLTW, - "@EnableLoadTimeWeaving is not present on importing class " + - importMetadata.getClassName()); + "@EnableLoadTimeWeaving is not present on importing class " + importMetadata.getClassName()); } @Override @@ -65,12 +65,13 @@ public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoade this.beanClassLoader = beanClassLoader; } + @Bean(name=ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public LoadTimeWeaver loadTimeWeaver() { LoadTimeWeaver loadTimeWeaver = null; - if (ltwConfigurer != null) { + if (this.ltwConfigurer != null) { // the user has provided a custom LTW instance loadTimeWeaver = ltwConfigurer.getLoadTimeWeaver(); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/MetadataUtils.java b/spring-context/src/main/java/org/springframework/context/annotation/MetadataUtils.java deleted file mode 100644 index a2dc4b36105..00000000000 --- a/spring-context/src/main/java/org/springframework/context/annotation/MetadataUtils.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.annotation; - -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.core.type.MethodMetadata; - -/** - * Convenience methods adapting {@link AnnotationMetadata} and {@link MethodMetadata} - * annotation attribute maps to the {@link AnnotationAttributes} API. As of Spring 3.1.1, - * both the reflection- and ASM-based implementations of these SPIs return - * {@link AnnotationAttributes} instances anyway, but for backward-compatibility, their - * signatures still return Maps. Therefore, for the usual case, these methods perform - * little more than a cast from Map to AnnotationAttributes. - * - * @author Chris Beams - * @since 3.1.1 - * @see AnnotationAttributes#fromMap(java.util.Map) - */ -class MetadataUtils { - - public static AnnotationAttributes attributesFor(AnnotationMetadata metadata, Class annoClass) { - return attributesFor(metadata, annoClass.getName()); - } - - public static AnnotationAttributes attributesFor(AnnotationMetadata metadata, String annoClassName) { - return AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(annoClassName, false)); - } - - public static AnnotationAttributes attributesFor(MethodMetadata metadata, Class targetAnno) { - return AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(targetAnno.getName())); - } - -} diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ImportAwareTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ImportAwareTests.java index 19834049030..6f353c04934 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ImportAwareTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ImportAwareTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,6 @@ import org.springframework.util.Assert; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; -import static org.springframework.context.annotation.MetadataUtils.*; /** * Tests that an ImportAware @Configuration classes gets injected with the @@ -59,7 +58,7 @@ public class ImportAwareTests { AnnotationMetadata importMetadata = importAwareConfig.importMetadata; assertThat("import metadata was not injected", importMetadata, notNullValue()); assertThat(importMetadata.getClassName(), is(ImportingConfig.class.getName())); - AnnotationAttributes importAttribs = attributesFor(importMetadata, Import.class); + AnnotationAttributes importAttribs = AnnotationConfigUtils.attributesFor(importMetadata, Import.class); Class[] importedClasses = importAttribs.getClassArray("value"); assertThat(importedClasses[0].getName(), is(ImportedConfig.class.getName())); } @@ -76,7 +75,7 @@ public class ImportAwareTests { AnnotationMetadata importMetadata = importAwareConfig.importMetadata; assertThat("import metadata was not injected", importMetadata, notNullValue()); assertThat(importMetadata.getClassName(), is(IndirectlyImportingConfig.class.getName())); - AnnotationAttributes enableAttribs = attributesFor(importMetadata, EnableImportedConfig.class); + AnnotationAttributes enableAttribs = AnnotationConfigUtils.attributesFor(importMetadata, EnableImportedConfig.class); String foo = enableAttribs.getString("foo"); assertThat(foo, is("xyz")); } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/RoleAnnotationTests.java b/spring-context/src/test/java/org/springframework/context/annotation/RoleAndDescriptionAnnotationTests.java similarity index 73% rename from spring-context/src/test/java/org/springframework/context/annotation/RoleAnnotationTests.java rename to spring-context/src/test/java/org/springframework/context/annotation/RoleAndDescriptionAnnotationTests.java index 436ae5a9423..a09df1ac43b 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/RoleAnnotationTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/RoleAndDescriptionAnnotationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,22 +16,23 @@ package org.springframework.context.annotation; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - import org.junit.Test; + import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.role.ComponentWithRole; import org.springframework.context.annotation.role.ComponentWithoutRole; +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; + /** - * Tests the use of the @Role annotation on @Bean methods and - * @Component classes. + * Tests the use of the @Role and @Description annotation on @Bean methods and @Component classes. * * @author Chris Beams + * @author Juergen Hoeller * @since 3.1 */ -public class RoleAnnotationTests { +public class RoleAndDescriptionAnnotationTests { @Test public void onBeanMethod() { @@ -40,8 +41,37 @@ public class RoleAnnotationTests { ctx.refresh(); assertThat("Expected bean to have ROLE_APPLICATION", ctx.getBeanDefinition("foo").getRole(), is(BeanDefinition.ROLE_APPLICATION)); + assertThat(ctx.getBeanDefinition("foo").getDescription(), is((Object) null)); assertThat("Expected bean to have ROLE_INFRASTRUCTURE", ctx.getBeanDefinition("bar").getRole(), is(BeanDefinition.ROLE_INFRASTRUCTURE)); + assertThat(ctx.getBeanDefinition("bar").getDescription(), is("A Bean method with a role")); + } + + @Test + public void onComponentClass() { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + ctx.register(ComponentWithoutRole.class, ComponentWithRole.class); + ctx.refresh(); + assertThat("Expected bean to have ROLE_APPLICATION", + ctx.getBeanDefinition("componentWithoutRole").getRole(), is(BeanDefinition.ROLE_APPLICATION)); + assertThat(ctx.getBeanDefinition("componentWithoutRole").getDescription(), is((Object) null)); + assertThat("Expected bean to have ROLE_INFRASTRUCTURE", + ctx.getBeanDefinition("componentWithRole").getRole(), is(BeanDefinition.ROLE_INFRASTRUCTURE)); + assertThat(ctx.getBeanDefinition("componentWithRole").getDescription(), is("A Component with a role")); + } + + + @Test + public void viaComponentScanning() { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + ctx.scan("org.springframework.context.annotation.role"); + ctx.refresh(); + assertThat("Expected bean to have ROLE_APPLICATION", + ctx.getBeanDefinition("componentWithoutRole").getRole(), is(BeanDefinition.ROLE_APPLICATION)); + assertThat(ctx.getBeanDefinition("componentWithoutRole").getDescription(), is((Object) null)); + assertThat("Expected bean to have ROLE_INFRASTRUCTURE", + ctx.getBeanDefinition("componentWithRole").getRole(), is(BeanDefinition.ROLE_INFRASTRUCTURE)); + assertThat(ctx.getBeanDefinition("componentWithRole").getDescription(), is("A Component with a role")); } @@ -54,32 +84,10 @@ public class RoleAnnotationTests { @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) + @Description("A Bean method with a role") public String bar() { return "bar"; } } - - @Test - public void onComponentClass() { - AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); - ctx.register(ComponentWithoutRole.class, ComponentWithRole.class); - ctx.refresh(); - assertThat("Expected bean to have ROLE_APPLICATION", - ctx.getBeanDefinition("componentWithoutRole").getRole(), is(BeanDefinition.ROLE_APPLICATION)); - assertThat("Expected bean to have ROLE_INFRASTRUCTURE", - ctx.getBeanDefinition("componentWithRole").getRole(), is(BeanDefinition.ROLE_INFRASTRUCTURE)); - } - - - @Test - public void viaComponentScanning() { - AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); - ctx.scan("org.springframework.context.annotation.role"); - ctx.refresh(); - assertThat("Expected bean to have ROLE_APPLICATION", - ctx.getBeanDefinition("componentWithoutRole").getRole(), is(BeanDefinition.ROLE_APPLICATION)); - assertThat("Expected bean to have ROLE_INFRASTRUCTURE", - ctx.getBeanDefinition("componentWithRole").getRole(), is(BeanDefinition.ROLE_INFRASTRUCTURE)); - } } diff --git a/spring-context/src/test/java/org/springframework/context/annotation/role/ComponentWithRole.java b/spring-context/src/test/java/org/springframework/context/annotation/role/ComponentWithRole.java index 85e8de9f82d..4d209d01ed0 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/role/ComponentWithRole.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/role/ComponentWithRole.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,12 @@ package org.springframework.context.annotation.role; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Description; import org.springframework.context.annotation.Role; import org.springframework.stereotype.Component; @Component("componentWithRole") @Role(BeanDefinition.ROLE_INFRASTRUCTURE) +@Description("A Component with a role") public class ComponentWithRole { } \ No newline at end of file