Infer AnnotationAttributes method return types

- Drop 'expectedType' parameter from #getClass and #getEnum methods and
   rely on compiler inference based on type of assigned variable, e.g.

     public @interface Example {
         Color color();
         Class<? extends UserType> userType();
         int order() default 0;
     }

     AnnotationAttributes example =
        AnnotationUtils.getAnnotationAttributes(Example.class, true, true);

     Color color = example.getEnum("color");
     Class<? extends UserType> userType = example.getClass("userType");

   or in cases where there is no variable assignment (and thus no
   inference possible), use explicit generic type, e.g.

     bean.setColor(example.<Color>getEnum("color"));

 - Rename #get{Int=>Number} and update return type from int to
   <N extends Number>, allowing invocations such as:

     int order = example.getNumber("order");

These changes reduce the overall number of methods exposed by
AnnotationAttributes, while at the same time providing comprehensive
access to all possible annotation attribute types -- that is, instead of
requiring explicit #getInt, #getFloat, #getDouble methods, the
single #getNumber method is capabable of handling them all, and without
any casting required. And the obvious additional benefit is more concise
invocation as no redundant 'expectedType' parameters are required.
This commit is contained in:
Chris Beams
2012-02-13 15:01:05 +01:00
parent 997c6c56f7
commit e25f1cbca9
13 changed files with 45 additions and 47 deletions
@@ -44,7 +44,7 @@ public class ProxyCachingConfiguration extends AbstractCachingConfiguration {
new BeanFactoryCacheOperationSourceAdvisor();
advisor.setCacheOperationSource(cacheOperationSource());
advisor.setAdvice(cacheInterceptor());
advisor.setOrder(this.enableCaching.getInt("order"));
advisor.setOrder(this.enableCaching.<Integer>getNumber("order"));
return advisor;
}
@@ -73,8 +73,7 @@ public abstract class AdviceModeImportSelector<A extends Annotation> implements
"@%s is not present on importing class '%s' as expected",
annoType.getSimpleName(), importingClassMetadata.getClassName()));
AdviceMode adviceMode =
attributes.getEnum(this.getAdviceModeAttributeName(), AdviceMode.class);
AdviceMode adviceMode = attributes.getEnum(this.getAdviceModeAttributeName());
String[] imports = selectImports(adviceMode);
Assert.notNull(imports, String.format("Unknown AdviceMode: '%s'", adviceMode));
@@ -232,8 +232,8 @@ public class AnnotationConfigUtils {
}
if (abd instanceof AbstractBeanDefinition) {
if (metadata.isAnnotated(Role.class.getName())) {
((AbstractBeanDefinition)abd).setRole(
attributesFor(metadata, Role.class).getInt("value"));
int role = attributesFor(metadata, Role.class).getNumber("value");
((AbstractBeanDefinition)abd).setRole(role);
}
}
}
@@ -81,7 +81,7 @@ public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver {
attributesFor(annDef.getMetadata(), this.scopeAnnotationType);
if (attributes != null) {
metadata.setScopeName(attributes.getString("value"));
ScopedProxyMode proxyMode = attributes.getEnum("proxyMode", ScopedProxyMode.class);
ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
if (proxyMode == null || proxyMode == ScopedProxyMode.DEFAULT) {
proxyMode = this.defaultProxyMode;
}
@@ -70,15 +70,15 @@ class ComponentScanAnnotationParser {
Assert.notNull(this.resourceLoader, "ResourceLoader must not be null");
scanner.setResourceLoader(this.resourceLoader);
scanner.setBeanNameGenerator(BeanUtils.instantiateClass(
componentScan.getClass("nameGenerator", BeanNameGenerator.class)));
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
scanner.setBeanNameGenerator(BeanUtils.instantiateClass(generatorClass));
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy", ScopedProxyMode.class);
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
} else {
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(
componentScan.getClass("scopeResolver", ScopeMetadataResolver.class)));
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
@@ -118,7 +118,7 @@ class ComponentScanAnnotationParser {
private List<TypeFilter> typeFiltersFor(AnnotationAttributes filterAttributes) {
List<TypeFilter> typeFilters = new ArrayList<TypeFilter>();
FilterType filterType = filterAttributes.getEnum("type", FilterType.class);
FilterType filterType = filterAttributes.getEnum("type");
for (Class<?> filterClass : filterAttributes.getClassArray("value")) {
switch (filterType) {
@@ -198,7 +198,7 @@ class ConfigurationClassBeanDefinitionReader {
// consider role
AnnotationAttributes role = attributesFor(metadata, Role.class);
if (role != null) {
beanDef.setRole(role.getInt("value"));
beanDef.setRole(role.<Integer>getNumber("value"));
}
// consider name and any aliases
@@ -246,7 +246,7 @@ class ConfigurationClassBeanDefinitionReader {
}
}
Autowire autowire = bean.getEnum("autowire", Autowire.class);
Autowire autowire = bean.getEnum("autowire");
if (autowire.isAutowire()) {
beanDef.setAutowireMode(autowire.value());
}
@@ -266,7 +266,7 @@ class ConfigurationClassBeanDefinitionReader {
AnnotationAttributes scope = attributesFor(metadata, Scope.class);
if (scope != null) {
beanDef.setScope(scope.getString("value"));
proxyMode = scope.getEnum("proxyMode", ScopedProxyMode.class);
proxyMode = scope.getEnum("proxyMode");
if (proxyMode == ScopedProxyMode.DEFAULT) {
proxyMode = ScopedProxyMode.NO;
}
@@ -216,8 +216,7 @@ class ConfigurationClassParser {
if (metadata.isAnnotated(ImportResource.class.getName())) {
AnnotationAttributes importResource = attributesFor(metadata, ImportResource.class);
String[] resources = importResource.getStringArray("value");
Class<? extends BeanDefinitionReader> readerClass =
importResource.getClass("reader", BeanDefinitionReader.class);
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
configClass.addImportedResource(resource, readerClass);
}
@@ -18,8 +18,6 @@ package org.springframework.context.annotation;
import static org.springframework.context.weaving.AspectJWeavingEnabler.ASPECTJ_AOP_XML_RESOURCE;
import java.util.Map;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -80,7 +78,8 @@ public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoade
loadTimeWeaver = new DefaultContextLoadTimeWeaver(this.beanClassLoader);
}
switch (this.enableLTW.getEnum("aspectjWeaving", AspectJWeaving.class)) {
AspectJWeaving aspectJWeaving = this.enableLTW.getEnum("aspectjWeaving");
switch (aspectJWeaving) {
case DISABLED:
// AJ weaving is disabled -> do nothing
break;
@@ -46,7 +46,7 @@ public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration {
AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();
Class<? extends Annotation> customAsyncAnnotation = enableAsync.getClass("annotation", Annotation.class);
Class<? extends Annotation> customAsyncAnnotation = enableAsync.getClass("annotation");
if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation")) {
bpp.setAsyncAnnotationType(customAsyncAnnotation);
}
@@ -56,8 +56,7 @@ public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration {
}
bpp.setProxyTargetClass(this.enableAsync.getBoolean("proxyTargetClass"));
bpp.setOrder(this.enableAsync.getInt("order"));
bpp.setOrder(this.enableAsync.<Integer>getNumber("order"));
return bpp;
}