Polishing

This commit is contained in:
Juergen Hoeller
2013-11-22 23:29:54 +01:00
parent 70164cb145
commit f39bb02628
6 changed files with 50 additions and 54 deletions

View File

@@ -22,6 +22,7 @@ import java.util.Arrays;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.scope.ScopedProxyFactoryBean;
import org.springframework.asm.Type;
import org.springframework.beans.factory.BeanFactory;
@@ -57,8 +58,6 @@ import org.springframework.util.ReflectionUtils;
*/
class ConfigurationClassEnhancer {
private static final Log logger = LogFactory.getLog(ConfigurationClassEnhancer.class);
private static final Callback[] CALLBACKS = new Callback[] {
new BeanMethodInterceptor(),
new DisposableBeanMethodInterceptor(),
@@ -66,12 +65,13 @@ class ConfigurationClassEnhancer {
NoOp.INSTANCE
};
private static final ConditionalCallbackFilter CALLBACK_FILTER =
new ConditionalCallbackFilter(CALLBACKS);
private static final ConditionalCallbackFilter CALLBACK_FILTER = new ConditionalCallbackFilter(CALLBACKS);
private static final String BEAN_FACTORY_FIELD = "$$beanFactory";
private static final Log logger = LogFactory.getLog(ConfigurationClassEnhancer.class);
/**
* Loads the specified class and generates a CGLIB subclass of it equipped with
* container-aware callbacks capable of respecting scoping and other bean semantics.
@@ -125,12 +125,13 @@ class ConfigurationClassEnhancer {
}
/**
* Uses enhancer to generate a subclass of superclass, ensuring that
* {@link #callbackInstances} are registered for the new subclass.
* Uses enhancer to generate a subclass of superclass,
* ensuring that callbacks are registered for the new subclass.
*/
private Class<?> createClass(Enhancer enhancer) {
Class<?> subclass = enhancer.createClass();
// registering callbacks statically (as opposed to threadlocal) is critical for usage in an OSGi env (SPR-5932)
// Registering callbacks statically (as opposed to thread-local)
// is critical for usage in an OSGi environment (SPR-5932)...
Enhancer.registerStaticCallbacks(subclass, CALLBACKS);
return subclass;
}
@@ -162,6 +163,7 @@ class ConfigurationClassEnhancer {
boolean isMatch(Method candidateMethod);
}
/**
* A {@link CallbackFilter} that works by interrogating {@link Callback}s in the order
* that they are defined via {@link ConditionalCallback}.
@@ -197,14 +199,14 @@ class ConfigurationClassEnhancer {
}
}
/**
* Intercepts the invocation of any {@link DisposableBean#destroy()} on @Configuration
* class instances for the purpose of de-registering CGLIB callbacks. This helps avoid
* garbage collection issues. See SPR-7901.
* @see EnhancedConfiguration
*/
private static class DisposableBeanMethodInterceptor implements MethodInterceptor,
ConditionalCallback {
private static class DisposableBeanMethodInterceptor implements MethodInterceptor, ConditionalCallback {
@Override
public boolean isMatch(Method candidateMethod) {
@@ -231,23 +233,20 @@ class ConfigurationClassEnhancer {
* Intercepts the invocation of any
* {@link BeanFactoryAware#setBeanFactory(BeanFactory)} on {@code @Configuration}
* class instances for the purpose of recording the {@link BeanFactory}.
*
* @see EnhancedConfiguration
*/
private static class BeanFactoryAwareMethodInterceptor implements MethodInterceptor,
ConditionalCallback {
private static class BeanFactoryAwareMethodInterceptor implements MethodInterceptor, ConditionalCallback {
@Override
public boolean isMatch(Method candidateMethod) {
return candidateMethod.getName().equals("setBeanFactory")
&& candidateMethod.getParameterTypes().length == 1
&& candidateMethod.getParameterTypes()[0].equals(BeanFactory.class)
&& BeanFactoryAware.class.isAssignableFrom(candidateMethod.getDeclaringClass());
return candidateMethod.getName().equals("setBeanFactory") &&
candidateMethod.getParameterTypes().length == 1 &&
candidateMethod.getParameterTypes()[0].equals(BeanFactory.class) &&
BeanFactoryAware.class.isAssignableFrom(candidateMethod.getDeclaringClass());
}
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
Field field = obj.getClass().getDeclaredField(BEAN_FACTORY_FIELD);
Assert.state(field != null, "Unable to find generated bean factory field");
field.set(obj, args[0]);
@@ -396,8 +395,7 @@ class ConfigurationClassEnhancer {
enhancer.setUseFactory(false);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
if (method.getName().equals("getObject") && args.length == 0) {
return beanFactory.getBean(beanName);
}
@@ -411,8 +409,8 @@ class ConfigurationClassEnhancer {
Field field = ReflectionUtils.findField(enhancedConfigInstance.getClass(), BEAN_FACTORY_FIELD);
Assert.state(field != null, "Unable to find generated bean factory field");
Object beanFactory = ReflectionUtils.getField(field, enhancedConfigInstance);
Assert.state(beanFactory != null, "The BeanFactory has not been injected into the @Configuration class");
Assert.state(beanFactory instanceof ConfigurableBeanFactory, "The injected BeanFactory is not a ConfigurableBeanFactory");
Assert.state(beanFactory != null, "BeanFactory has not been injected into @Configuration class");
Assert.state(beanFactory instanceof ConfigurableBeanFactory, "Injected BeanFactory is not a ConfigurableBeanFactory");
return (ConfigurableBeanFactory) beanFactory;
}
}

View File

@@ -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.
@@ -25,6 +25,7 @@ import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
* Abstract base {@code Configuration} class providing common structure for enabling
@@ -38,15 +39,16 @@ import org.springframework.util.Assert;
public abstract class AbstractAsyncConfiguration implements ImportAware {
protected AnnotationAttributes enableAsync;
protected Executor executor;
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableAsync = AnnotationAttributes.fromMap(
importMetadata.getAnnotationAttributes(EnableAsync.class.getName(), false));
Assert.notNull(this.enableAsync,
"@EnableAsync is not present on importing class " +
importMetadata.getClassName());
"@EnableAsync is not present on importing class " + importMetadata.getClassName());
}
/**
@@ -54,14 +56,12 @@ public abstract class AbstractAsyncConfiguration implements ImportAware {
*/
@Autowired(required = false)
void setConfigurers(Collection<AsyncConfigurer> configurers) {
if (configurers == null || configurers.isEmpty()) {
if (CollectionUtils.isEmpty(configurers)) {
return;
}
if (configurers.size() > 1) {
throw new IllegalStateException("only one AsyncConfigurer may exist");
throw new IllegalStateException("Only one AsyncConfigurer may exist");
}
AsyncConfigurer configurer = configurers.iterator().next();
this.executor = configurer.getAsyncExecutor();
}