提交 d4fdad22 编写于 作者: C Chris Beams

+ Further repackaging and consolidation

+ Tested compatibility with @Value (works, but noticed and filed an unrelated-to-javaconfig improvement. See SPR-5530)
上级 2689751c
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.config.java.annotation;
package org.springframework.config.java;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.config.java.model;
package org.springframework.config.java;
import static java.lang.String.*;
......@@ -24,7 +24,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.util.Assert;
import sun.security.x509.Extension;
......
......@@ -13,14 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.config.java.model;
package org.springframework.config.java;
import static java.lang.String.*;
import java.util.ArrayList;
import java.util.List;
import org.springframework.config.java.annotation.Configuration;
/**
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.config.java.model;
package org.springframework.config.java;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.config.java.model;
package org.springframework.config.java;
import java.util.ArrayList;
import java.util.Arrays;
......
......@@ -13,10 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.config.java.model;
package org.springframework.config.java;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.config.java.model;
package org.springframework.config.java;
import static java.lang.String.*;
import static org.springframework.config.java.Util.*;
......
......@@ -13,9 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.config.java.model;
package org.springframework.config.java;
import org.springframework.config.java.annotation.Configuration;
/**
......
......@@ -26,13 +26,13 @@ import java.util.List;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.model.ConfigurationClass;
import org.springframework.config.java.model.ConfigurationModel;
import org.springframework.config.java.model.Factory;
import org.springframework.config.java.model.ModelMethod;
import org.springframework.config.java.model.UsageError;
import org.springframework.config.java.model.Validator;
import org.springframework.config.java.Configuration;
import org.springframework.config.java.ConfigurationClass;
import org.springframework.config.java.ConfigurationModel;
import org.springframework.config.java.Factory;
import org.springframework.config.java.ModelMethod;
import org.springframework.config.java.UsageError;
import org.springframework.config.java.Validator;
/**
......
......@@ -13,12 +13,12 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.model.BeanDefinitionRegistrar;
import org.springframework.config.java.model.ConfigurationClass;
import org.springframework.config.java.model.MalformedJavaConfigurationException;
import org.springframework.config.java.model.ModelMethod;
import org.springframework.config.java.model.UsageError;
import org.springframework.config.java.BeanDefinitionRegistrar;
import org.springframework.config.java.Configuration;
import org.springframework.config.java.ConfigurationClass;
import org.springframework.config.java.MalformedJavaConfigurationException;
import org.springframework.config.java.ModelMethod;
import org.springframework.config.java.UsageError;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert;
......
......@@ -28,7 +28,9 @@ import org.objectweb.asm.MethodVisitor;
/**
* Transforms a class by adding bytecode for a class-level annotation.
* Checks to ensure that the desired annotation is not already present
* before adding.
* before adding. Used by {@link ConfigurationEnhancer} to dynamically add
* an {@link org.aspectj.lang.Aspect} annotation to an enhanced Configuration
* subclass.
* <p/>
* This class was originally adapted from examples the ASM 3.0 documentation.
*
......
/*
* Copyright 2002-2008 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.config.java.internal.enhancement;
import static java.lang.String.*;
import static org.springframework.config.java.Util.*;
import static org.springframework.util.Assert.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import net.sf.cglib.core.DefaultGeneratorStrategy;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.NoOp;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.model.BeanDefinitionRegistrar;
import org.springframework.config.java.model.ConfigurationClass;
import org.springframework.config.java.model.ConfigurationModel;
import org.springframework.config.java.model.ModelMethod;
/**
* Enhances {@link Configuration} classes by generating a CGLIB subclass capable of
* interacting with the Spring container to respect bean semantics.
*
* @see #enhance(String)
*
* @author Chris Beams
*/
public class CglibConfigurationEnhancer implements ConfigurationEnhancer {
private static final Log log = LogFactory.getLog(CglibConfigurationEnhancer.class);
private final ArrayList<Class<? extends Callback>> callbackTypes =
new ArrayList<Class<? extends Callback>>();
private final LinkedHashSet<BeanDefinitionRegistrar> handlers =
new LinkedHashSet<BeanDefinitionRegistrar>();
private final ArrayList<Callback> callbackInstances =
new ArrayList<Callback>();
private final CallbackFilter callbackFilter =
new CallbackFilter() {
public int accept(Method candidateMethod) {
Iterator<BeanDefinitionRegistrar> iter = handlers.iterator();
for(int i=0; iter.hasNext(); i++)
if(iter.next().accepts(candidateMethod))
return i;
throw new IllegalStateException(format("No registered handler is capable of " +
"handling method [%s]. Perhaps you forgot to register a catch-all registrar?",
candidateMethod.getName()));
}
};
/**
* Creates a new {@link CglibConfigurationEnhancer} instance.
*/
public CglibConfigurationEnhancer(DefaultListableBeanFactory beanFactory, ConfigurationModel model) {
notNull(beanFactory, "beanFactory must be non-null");
notNull(model, "model must be non-null");
populateHandlersAndCallbacks(beanFactory, model);
}
/**
* Reads the contents of {@code model} in order to populate {@link #handlers},
* {@link #callbackInstances} and {@link #callbackTypes} appropriately.
*
* @see #callbackFilter
*/
private void populateHandlersAndCallbacks(DefaultListableBeanFactory beanFactory, ConfigurationModel model) {
for (ConfigurationClass configClass : model.getAllConfigurationClasses()) {
for (ModelMethod method : configClass.getMethods()) {
handlers.add(method.getRegistrar());
Callback callback = method.getCallback();
if(callback instanceof BeanFactoryAware)
((BeanFactoryAware)callback).setBeanFactory(beanFactory);
callbackInstances.add(callback);
}
}
handlers.add(new InitializingBeanRegistrar());
callbackInstances.add(new InitializingBeanCallback(beanFactory));
// register a 'catch-all' registrar
handlers.add(new BeanDefinitionRegistrar() {
public boolean accepts(Method method) {
return true;
}
public void register(ModelMethod method, BeanDefinitionRegistry registry) {
// no-op
}
});
callbackInstances.add(NoOp.INSTANCE);
for(Callback callback : callbackInstances)
callbackTypes.add(callback.getClass());
}
/**
* Loads the specified class and generates a CGLIB subclass of it equipped with container-aware
* callbacks capable of respecting scoping and other bean semantics.
*/
public String enhance(String configClassName) {
if (log.isInfoEnabled())
log.info("Enhancing " + configClassName);
Class<?> superclass = loadRequiredClass(configClassName);
Class<?> subclass = createClass(newEnhancer(superclass), superclass);
subclass = nestOneClassDeeperIfAspect(superclass, subclass);
if (log.isInfoEnabled())
log.info(format("Successfully enhanced %s; enhanced class name is: %s",
configClassName, subclass.getName()));
return subclass.getName();
}
/**
* Creates a new CGLIB {@link Enhancer} instance.
*/
private Enhancer newEnhancer(Class<?> superclass) {
Enhancer enhancer = new Enhancer();
// because callbackFilter and callbackTypes are dynamically populated
// there's no opportunity for caching. This does not appear to be causing
// any performance problem.
enhancer.setUseCache(false);
enhancer.setSuperclass(superclass);
enhancer.setInterfaces(new Class<?>[]{InitializingBean.class});
enhancer.setUseFactory(false);
enhancer.setCallbackFilter(callbackFilter);
enhancer.setCallbackTypes(callbackTypes.toArray(new Class<?>[]{}));
return enhancer;
}
/**
* Uses enhancer to generate a subclass of superclass, ensuring that
* {@link #callbackInstances} are registered for the new subclass.
*/
private Class<?> createClass(Enhancer enhancer, Class<?> superclass) {
Class<?> subclass = enhancer.createClass();
// see #registerThreadLocalCleanupBeanDefinition
Enhancer.registerCallbacks(subclass, callbackInstances.toArray(new Callback[] {}));
//Enhancer.registerStaticCallbacks(subclass, callbackInstances.toArray(new Callback[] {}));
return subclass;
}
/**
* Works around a constraint imposed by the AspectJ 5 annotation-style programming model. See
* comments inline for detail.
*
* @return original subclass instance unless superclass is annnotated with @Aspect, in which
* case a subclass of the subclass is returned
*/
private Class<?> nestOneClassDeeperIfAspect(Class<?> superclass, Class<?> origSubclass) {
boolean superclassIsAnAspect = false;
// check for @Aspect by name rather than by class literal to avoid
// requiring AspectJ as a runtime dependency.
for(Annotation anno : superclass.getAnnotations())
if(anno.annotationType().getName().equals("org.aspectj.lang.annotation.Aspect"))
superclassIsAnAspect = true;
if(!superclassIsAnAspect)
return origSubclass;
// the superclass is annotated with AspectJ's @Aspect.
// this means that we must create a subclass of the subclass
// in order to avoid some guard logic in Spring core that disallows
// extending a concrete aspect class.
Enhancer enhancer = newEnhancer(origSubclass);
enhancer.setStrategy(new DefaultGeneratorStrategy() {
@Override
protected byte[] transform(byte[] b) throws Exception {
ClassWriter writer = new ClassWriter(false);
ClassAdapter adapter =
new AddAnnotationAdapter(writer, "Lorg/aspectj/lang/annotation/Aspect;");
ClassReader reader = new ClassReader(b);
reader.accept(adapter, false);
return writer.toByteArray();
}
});
// create a subclass of the original subclass
Class<?> newSubclass = createClass(enhancer, origSubclass);
return newSubclass;
}
}
......@@ -15,10 +15,223 @@
*/
package org.springframework.config.java.internal.enhancement;
import static java.lang.String.*;
import static org.springframework.config.java.Util.*;
import static org.springframework.util.Assert.*;
/** TODO: JAVADOC */
public interface ConfigurationEnhancer {
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
String enhance(String configClassName);
import net.sf.cglib.core.DefaultGeneratorStrategy;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.NoOp;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.config.java.BeanDefinitionRegistrar;
import org.springframework.config.java.Configuration;
import org.springframework.config.java.ConfigurationClass;
import org.springframework.config.java.ConfigurationModel;
import org.springframework.config.java.ModelMethod;
/**
* Enhances {@link Configuration} classes by generating a CGLIB subclass capable of
* interacting with the Spring container to respect bean semantics.
*
* @see #enhance(String)
*
* @author Chris Beams
*/
public class ConfigurationEnhancer {
private static final Log log = LogFactory.getLog(ConfigurationEnhancer.class);
private final ArrayList<Class<? extends Callback>> callbackTypes =
new ArrayList<Class<? extends Callback>>();
private final LinkedHashSet<BeanDefinitionRegistrar> registrars =
new LinkedHashSet<BeanDefinitionRegistrar>();
private final ArrayList<Callback> callbackInstances =
new ArrayList<Callback>();
private final CallbackFilter callbackFilter =
new CallbackFilter() {
public int accept(Method candidateMethod) {
Iterator<BeanDefinitionRegistrar> iter = registrars.iterator();
for(int i=0; iter.hasNext(); i++)
if(iter.next().accepts(candidateMethod))
return i;
throw new IllegalStateException(format("No registrar is capable of " +
"handling method [%s]. Perhaps you forgot to add a catch-all registrar?",
candidateMethod.getName()));
}
};
/**
* Creates a new {@link ConfigurationEnhancer} instance.
*/
public ConfigurationEnhancer(DefaultListableBeanFactory beanFactory, ConfigurationModel model) {
notNull(beanFactory, "beanFactory must be non-null");
notNull(model, "model must be non-null");
populateHandlersAndCallbacks(beanFactory, model);
}
/**
* Reads the contents of {@code model} in order to populate {@link #registrars},
* {@link #callbackInstances} and {@link #callbackTypes} appropriately.
*
* @see #callbackFilter
*/
private void populateHandlersAndCallbacks(DefaultListableBeanFactory beanFactory, ConfigurationModel model) {
for (ConfigurationClass configClass : model.getAllConfigurationClasses()) {
for (ModelMethod method : configClass.getMethods()) {
registrars.add(method.getRegistrar());
Callback callback = method.getCallback();
if(callback instanceof BeanFactoryAware)
((BeanFactoryAware)callback).setBeanFactory(beanFactory);
callbackInstances.add(callback);
}
}
registrars.add(new InitializingBeanRegistrar());
callbackInstances.add(new InitializingBeanCallback(beanFactory));
// register a 'catch-all' registrar
registrars.add(new BeanDefinitionRegistrar() {
public boolean accepts(Method method) {
return true;
}
public void register(ModelMethod method, BeanDefinitionRegistry registry) {
// no-op
}
});
callbackInstances.add(NoOp.INSTANCE);
for(Callback callback : callbackInstances)
callbackTypes.add(callback.getClass());
}
/**
* Loads the specified class and generates a CGLIB subclass of it equipped with container-aware
* callbacks capable of respecting scoping and other bean semantics.
*/
public String enhance(String configClassName) {
if (log.isInfoEnabled())
log.info("Enhancing " + configClassName);
Class<?> superclass = loadRequiredClass(configClassName);
Class<?> subclass = createClass(newEnhancer(superclass), superclass);
subclass = nestOneClassDeeperIfAspect(superclass, subclass);
if (log.isInfoEnabled())
log.info(format("Successfully enhanced %s; enhanced class name is: %s",
configClassName, subclass.getName()));
return subclass.getName();
}
/**
* Creates a new CGLIB {@link Enhancer} instance.
*/
private Enhancer newEnhancer(Class<?> superclass) {
Enhancer enhancer = new Enhancer();
// because callbackFilter and callbackTypes are dynamically populated
// there's no opportunity for caching. This does not appear to be causing
// any performance problem.
enhancer.setUseCache(false);
enhancer.setSuperclass(superclass);
enhancer.setInterfaces(new Class<?>[]{InitializingBean.class});
enhancer.setUseFactory(false);
enhancer.setCallbackFilter(callbackFilter);
enhancer.setCallbackTypes(callbackTypes.toArray(new Class<?>[]{}));
return enhancer;
}
/**
* Uses enhancer to generate a subclass of superclass, ensuring that
* {@link #callbackInstances} are registered for the new subclass.
*/
private Class<?> createClass(Enhancer enhancer, Class<?> superclass) {
Class<?> subclass = enhancer.createClass();
// see #registerThreadLocalCleanupBeanDefinition
Enhancer.registerCallbacks(subclass, callbackInstances.toArray(new Callback[] {}));
//Enhancer.registerStaticCallbacks(subclass, callbackInstances.toArray(new Callback[] {}));
return subclass;
}
/**
* Works around a constraint imposed by the AspectJ 5 annotation-style programming model. See
* comments inline for detail.
*
* @return original subclass instance unless superclass is annnotated with @Aspect, in which
* case a subclass of the subclass is returned
*/
private Class<?> nestOneClassDeeperIfAspect(Class<?> superclass, Class<?> origSubclass) {
boolean superclassIsAnAspect = false;
// check for @Aspect by name rather than by class literal to avoid
// requiring AspectJ as a runtime dependency.
for(Annotation anno : superclass.getAnnotations())
if(anno.annotationType().getName().equals("org.aspectj.lang.annotation.Aspect"))
superclassIsAnAspect = true;
if(!superclassIsAnAspect)
return origSubclass;
// the superclass is annotated with AspectJ's @Aspect.
// this means that we must create a subclass of the subclass
// in order to avoid some guard logic in Spring core that disallows
// extending a concrete aspect class.
Enhancer enhancer = newEnhancer(origSubclass);
enhancer.setStrategy(new DefaultGeneratorStrategy() {
@Override
protected byte[] transform(byte[] b) throws Exception {
ClassWriter writer = new ClassWriter(false);
ClassAdapter adapter =
new AddAnnotationAdapter(writer, "Lorg/aspectj/lang/annotation/Aspect;");
ClassReader reader = new ClassReader(b);
reader.accept(adapter, false);
return writer.toByteArray();
}
});
// create a subclass of the original subclass
Class<?> newSubclass = createClass(enhancer, origSubclass);
return newSubclass;
}
}
......@@ -18,8 +18,8 @@ package org.springframework.config.java.internal.enhancement;
import java.lang.reflect.Method;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.config.java.model.BeanDefinitionRegistrar;
import org.springframework.config.java.model.ModelMethod;
import org.springframework.config.java.BeanDefinitionRegistrar;
import org.springframework.config.java.ModelMethod;
class InitializingBeanRegistrar implements BeanDefinitionRegistrar {
public boolean accepts(Method method) {
......
......@@ -25,13 +25,13 @@ import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.support.BeanDefinitionReader;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.Configuration;
import org.springframework.config.java.ConfigurationModel;
import org.springframework.config.java.MalformedJavaConfigurationException;
import org.springframework.config.java.UsageError;
import org.springframework.config.java.internal.parsing.ConfigurationParser;
import org.springframework.config.java.internal.parsing.asm.AsmConfigurationParser;
import org.springframework.config.java.internal.parsing.asm.AsmUtils;
import org.springframework.config.java.model.ConfigurationModel;
import org.springframework.config.java.model.MalformedJavaConfigurationException;
import org.springframework.config.java.model.UsageError;
import org.springframework.core.io.ClassPathResource;
......
......@@ -32,11 +32,11 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.model.ConfigurationClass;
import org.springframework.config.java.model.ConfigurationModel;
import org.springframework.config.java.model.Factory;
import org.springframework.config.java.model.ModelMethod;
import org.springframework.config.java.Configuration;
import org.springframework.config.java.ConfigurationClass;
import org.springframework.config.java.ConfigurationModel;
import org.springframework.config.java.Factory;
import org.springframework.config.java.ModelMethod;
import org.springframework.config.java.plugin.Extension;
import org.springframework.config.java.plugin.ExtensionAnnotationBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationUtils;
......
......@@ -15,8 +15,8 @@
*/
package org.springframework.config.java.internal.parsing;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.model.ConfigurationModel;
import org.springframework.config.java.Configuration;
import org.springframework.config.java.ConfigurationModel;
/**
......@@ -26,7 +26,7 @@ import org.springframework.config.java.model.ConfigurationModel;
* from the process of registering bean definitions based on the content of that class.
*
* @see org.springframework.config.java.internal.parsing.asm.AsmConfigurationParser
* @see org.springframework.config.java.model.ConfigurationModel
* @see org.springframework.config.java.ConfigurationModel
* @see org.springframework.config.java.internal.factory.support.ConfigurationModelBeanDefinitionReader
*
* @author Chris Beams
......@@ -39,7 +39,7 @@ public interface ConfigurationParser {
* @param configurationSource representation of a Configuration class, may be java.lang.Class,
* ASM representation or otherwise
*
* @see org.springframework.config.java.annotation.Configuration
* @see org.springframework.config.java.Configuration
*/
void parse(Object configurationSource);
......@@ -52,7 +52,7 @@ public interface ConfigurationParser {
* @param configurationId name of this configuration class, probably corresponding to a
* bean id
*
* @see org.springframework.config.java.annotation.Configuration
* @see org.springframework.config.java.Configuration
* @see org.springframework.config.java.process.ConfigurationPostProcessor
*/
void parse(Object configurationSource, String configurationId);
......
......@@ -18,10 +18,10 @@ package org.springframework.config.java.internal.parsing.asm;
import org.objectweb.asm.ClassReader;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.Configuration;
import org.springframework.config.java.ConfigurationClass;
import org.springframework.config.java.ConfigurationModel;
import org.springframework.config.java.internal.parsing.ConfigurationParser;
import org.springframework.config.java.model.ConfigurationClass;
import org.springframework.config.java.model.ConfigurationModel;
import org.springframework.util.Assert;
......
......@@ -28,11 +28,11 @@ import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodAdapter;
import org.objectweb.asm.Opcodes;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.model.ConfigurationClass;
import org.springframework.config.java.model.Factory;
import org.springframework.config.java.model.ModelClass;
import org.springframework.config.java.model.ModelMethod;
import org.springframework.config.java.Configuration;
import org.springframework.config.java.ConfigurationClass;
import org.springframework.config.java.Factory;
import org.springframework.config.java.ModelClass;
import org.springframework.config.java.ModelMethod;
/**
* Visits a single method declared in a given {@link Configuration} class. Determines whether the
......
......@@ -29,9 +29,9 @@ import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.model.ConfigurationClass;
import org.springframework.config.java.model.ConfigurationModel;
import org.springframework.config.java.Configuration;
import org.springframework.config.java.ConfigurationClass;
import org.springframework.config.java.ConfigurationModel;
import org.springframework.config.java.plugin.Extension;
import org.springframework.util.ClassUtils;
......
......@@ -27,11 +27,10 @@ import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.internal.enhancement.CglibConfigurationEnhancer;
import org.springframework.config.java.Configuration;
import org.springframework.config.java.ConfigurationModel;
import org.springframework.config.java.internal.enhancement.ConfigurationEnhancer;
import org.springframework.config.java.internal.factory.support.AsmJavaConfigBeanDefinitionReader;
import org.springframework.config.java.model.ConfigurationModel;
import org.springframework.config.java.process.ConfigurationPostProcessor;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.ClassUtils;
......@@ -48,11 +47,15 @@ public class InternalConfigurationPostProcessor implements BeanFactoryPostProces
* necessary to fulfill JavaConfig requirements.
*/
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if(!(beanFactory instanceof DefaultListableBeanFactory))
throw new IllegalStateException("beanFactory must be of type "
+ DefaultListableBeanFactory.class.getSimpleName());
ConfigurationModel model = new ConfigurationModel();
parseAnyConfigurationClasses(beanFactory, model);
enhanceAnyConfigurationClasses(beanFactory, model);
enhanceAnyConfigurationClasses((DefaultListableBeanFactory) beanFactory, model);
}
private void parseAnyConfigurationClasses(ConfigurableListableBeanFactory beanFactory, ConfigurationModel model) {
......@@ -84,14 +87,9 @@ public class InternalConfigurationPostProcessor implements BeanFactoryPostProces
* @see ConfigurationEnhancer
* @see BeanFactoryPostProcessor
*/
private void enhanceAnyConfigurationClasses(ConfigurableListableBeanFactory clbf, ConfigurationModel model) {
if(!(clbf instanceof DefaultListableBeanFactory))
throw new IllegalStateException("beanFactory must be of type "
+ DefaultListableBeanFactory.class.getSimpleName());
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)clbf;
private void enhanceAnyConfigurationClasses(DefaultListableBeanFactory beanFactory, ConfigurationModel model) {
ConfigurationEnhancer enhancer = new CglibConfigurationEnhancer(beanFactory, model);
ConfigurationEnhancer enhancer = new ConfigurationEnhancer(beanFactory, model);
int configClassesEnhanced = 0;
......
......@@ -19,7 +19,7 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.Configuration;
import org.springframework.config.java.internal.process.InternalConfigurationPostProcessor;
import org.springframework.core.Ordered;
......
......@@ -5,7 +5,8 @@ import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.config.java.Configuration;
import org.springframework.config.java.ext.Bean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
......@@ -36,4 +37,26 @@ public class AutowiredConfigurationTests {
public @Bean Colour colour() { return Colour.RED; }
}
public @Test void testValueInjection() {
System.setProperty("myProp", "foo");
ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext(
"ValueInjectionTests.xml", AutowiredConfigurationTests.class);
TestBean testBean = factory.getBean("testBean", TestBean.class);
assertThat(testBean.getName(), equalTo("foo"));
}
@Configuration
static class ValueConfig {
@Value("#{systemProperties.myProp}")
private String name = "default";
public @Bean TestBean testBean() {
return new TestBean(name);
}
}
}
......@@ -9,7 +9,7 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.Configuration;
import org.springframework.config.java.ext.Bean;
import org.springframework.config.java.process.ConfigurationPostProcessor;
import org.springframework.config.java.util.DefaultScopes;
......
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
xmlns:context="http://www.springframework.org/schema/context">
<context:annotation-config/>
<bean class="org.springframework.config.java.process.ConfigurationPostProcessor"/>
<bean class="test.basic.AutowiredConfigurationTests$ValueConfig"/>
</beans>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册