Avoid synthesizable annotation creation for @Bean/@Scope processing

Includes consistent (non-)use of AnnotationUtils/AnnotatedElementUtils.

Issue: SPR-16933
This commit is contained in:
Juergen Hoeller
2018-08-01 11:43:28 +02:00
parent 9b671f8408
commit 589b7048ec
6 changed files with 68 additions and 47 deletions

View File

@@ -17,8 +17,11 @@
package org.springframework.context.annotation;
import java.lang.reflect.Method;
import java.util.Map;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.util.ConcurrentReferenceHashMap;
/**
* Utilities for processing {@link Bean}-annotated methods.
@@ -27,10 +30,11 @@ import org.springframework.core.annotation.AnnotatedElementUtils;
* @author Juergen Hoeller
* @since 3.1
*/
final class BeanAnnotationHelper {
abstract class BeanAnnotationHelper {
private BeanAnnotationHelper() {
}
private static final Map<Method, String> beanNameCache = new ConcurrentReferenceHashMap<>();
private static final Map<Method, Boolean> scopedProxyCache = new ConcurrentReferenceHashMap<>();
public static boolean isBeanAnnotated(Method method) {
@@ -38,16 +42,33 @@ final class BeanAnnotationHelper {
}
public static String determineBeanNameFor(Method beanMethod) {
// By default, the bean name is the name of the @Bean-annotated method
String beanName = beanMethod.getName();
// Check to see if the user has explicitly set a custom bean name...
Bean bean = AnnotatedElementUtils.findMergedAnnotation(beanMethod, Bean.class);
if (bean != null && bean.name().length > 0) {
beanName = bean.name()[0];
String beanName = beanNameCache.get(beanMethod);
if (beanName == null) {
// By default, the bean name is the name of the @Bean-annotated method
beanName = beanMethod.getName();
// Check to see if the user has explicitly set a custom bean name...
AnnotationAttributes bean =
AnnotatedElementUtils.findMergedAnnotationAttributes(beanMethod, Bean.class, false, false);
if (bean != null) {
String[] names = bean.getStringArray("name");
if (names.length > 0) {
beanName = names[0];
}
}
beanNameCache.put(beanMethod, beanName);
}
return beanName;
}
public static boolean isScopedProxy(Method beanMethod) {
Boolean scopedProxy = scopedProxyCache.get(beanMethod);
if (scopedProxy == null) {
AnnotationAttributes scope =
AnnotatedElementUtils.findMergedAnnotationAttributes(beanMethod, Scope.class, false, false);
scopedProxy = (scope != null && scope.getEnum("proxyMode") != ScopedProxyMode.NO);
scopedProxyCache.put(beanMethod, scopedProxy);
}
return scopedProxy;
}
}

View File

@@ -47,7 +47,6 @@ import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;
import org.springframework.cglib.transform.ClassEmitterTransformer;
import org.springframework.cglib.transform.TransformingClassGenerator;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.lang.Nullable;
import org.springframework.objenesis.ObjenesisException;
import org.springframework.objenesis.SpringObjenesis;
@@ -317,8 +316,7 @@ class ConfigurationClassEnhancer {
String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);
// Determine whether this bean is a scoped-proxy
Scope scope = AnnotatedElementUtils.findMergedAnnotation(beanMethod, Scope.class);
if (scope != null && scope.proxyMode() != ScopedProxyMode.NO) {
if (BeanAnnotationHelper.isScopedProxy(beanMethod)) {
String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
beanName = scopedBeanName;