+ Renamed Scopes -> StandardScopes
+ Renamed ConfigurationPostProcessor -> ConfigurationClassPostProcessor + JavaDoc and polish for AbstractConfigurationClassProcessor
This commit is contained in:
parent
8610c0bce8
commit
2e7e982487
|
|
@ -26,9 +26,9 @@ package org.springframework.config.java;
|
|||
* @author Chris Beams
|
||||
* @since 3.0
|
||||
*/
|
||||
public class Scopes {
|
||||
public class StandardScopes {
|
||||
|
||||
private Scopes() {
|
||||
private StandardScopes() {
|
||||
}
|
||||
|
||||
public static final String SINGLETON = "singleton";
|
||||
|
|
@ -26,7 +26,7 @@ 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.Configuration;
|
||||
import org.springframework.config.java.Scopes;
|
||||
import org.springframework.config.java.StandardScopes;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -87,7 +87,7 @@ public @interface Bean {
|
|||
* Scope: whether the bean is a singleton, prototype or custom scope. Default is
|
||||
* singleton.
|
||||
*/
|
||||
String scope() default Scopes.SINGLETON;
|
||||
String scope() default StandardScopes.SINGLETON;
|
||||
|
||||
/**
|
||||
* Bean autowire strategy.
|
||||
|
|
|
|||
|
|
@ -1,47 +1,108 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.support;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.config.java.Configuration;
|
||||
import org.springframework.config.java.ConfigurationModel;
|
||||
import org.springframework.config.java.MalformedConfigurationException;
|
||||
import org.springframework.config.java.ext.Bean;
|
||||
import org.springframework.config.java.internal.parsing.ConfigurationParser;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract superclass for processing {@link Configuration}-annotated classes and registering
|
||||
* bean definitions based on {@link Bean}-annotated methods within those classes.
|
||||
*
|
||||
* <p>Provides template method {@link #processConfigBeanDefinitions()} that orchestrates calling each
|
||||
* of several abstract methods to be overriden by concrete implementations that allow for
|
||||
* customizing how {@link Configuration} classes are found ({@link #getConfigurationBeanDefinitions}),
|
||||
* customizing the creation of a {@link ConfigurationParser} ({@link #createConfigurationParser}),
|
||||
* and customizing {@link ConfigurationModel} validation logic ({@link #validateModel}).
|
||||
*
|
||||
* <p>This class was expressly designed with tooling in mind. Spring IDE will maintain it's
|
||||
* own implementation of this class but still take advantage of the generic parsing algorithm
|
||||
* defined here by {@link #processConfigBeanDefinitions()}.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.0
|
||||
* @see ConfigurationClassPostProcessor
|
||||
*/
|
||||
public abstract class AbstractConfigurationClassProcessor {
|
||||
|
||||
|
||||
/**
|
||||
* Populate and return a registry containing all {@link Configuration} bean definitions
|
||||
* to be processed.
|
||||
*
|
||||
* @param includeAbstractBeanDefs whether abstract Configuration bean definitions should
|
||||
* be included in the resulting BeanDefinitionRegistry. Usually false, but called as true
|
||||
* during the enhancement phase.
|
||||
* @see #processConfigBeanDefinitions()
|
||||
*/
|
||||
protected abstract BeanDefinitionRegistry getConfigurationBeanDefinitions(boolean includeAbstractBeanDefs);
|
||||
|
||||
/**
|
||||
* Create and return a new {@link ConfigurationParser}, allowing for customization of
|
||||
* type (ASM/JDT/Reflection) as well as providing specialized ClassLoader during
|
||||
* construction.
|
||||
* @see #processConfigBeanDefinitions()
|
||||
*/
|
||||
protected abstract ConfigurationParser createConfigurationParser();
|
||||
|
||||
/**
|
||||
* Validate the given model and handle any errors. Implementations may choose to throw
|
||||
* {@link MalformedConfigurationException}, or in the case of tooling register problems
|
||||
* with the UI.
|
||||
* @param configModel {@link ConfigurationModel} to validate
|
||||
*/
|
||||
protected abstract void validateModel(ConfigurationModel configModel);
|
||||
|
||||
protected BeanDefinitionRegistry processConfigBeanDefinitions() {
|
||||
/**
|
||||
* Build and validate a {@link ConfigurationModel} based on the registry of
|
||||
* {@link Configuration} classes provided by {@link #getConfigurationBeanDefinitions},
|
||||
* then, based on the content of that model, create and register bean definitions
|
||||
* against a new {@link BeanDefinitionRegistry}, then return the registry.
|
||||
*
|
||||
* @return registry containing one bean definition per {@link Bean} method declared
|
||||
* within the Configuration classes
|
||||
*/
|
||||
protected final BeanDefinitionRegistry processConfigBeanDefinitions() {
|
||||
BeanDefinitionRegistry configBeanDefs = getConfigurationBeanDefinitions(false);
|
||||
|
||||
// return an empty registry immediately if no @Configuration classes were found
|
||||
if(configBeanDefs.getBeanDefinitionCount() == 0)
|
||||
return configBeanDefs; // nothing to do - don't waste any more cycles
|
||||
return configBeanDefs;
|
||||
|
||||
ConfigurationModel configModel = createConfigurationModelFor(configBeanDefs);
|
||||
// populate a new ConfigurationModel by parsing each @Configuration classes
|
||||
ConfigurationParser parser = createConfigurationParser();
|
||||
|
||||
for(String beanName : configBeanDefs.getBeanDefinitionNames()) {
|
||||
BeanDefinition beanDef = configBeanDefs.getBeanDefinition(beanName);
|
||||
String className = beanDef.getBeanClassName();
|
||||
|
||||
parser.parse(className, beanName);
|
||||
}
|
||||
|
||||
ConfigurationModel configModel = parser.getConfigurationModel();
|
||||
|
||||
// validate the ConfigurationModel
|
||||
validateModel(configModel);
|
||||
|
||||
return renderModelAsBeanDefinitions(configModel);
|
||||
}
|
||||
|
||||
private ConfigurationModel createConfigurationModelFor(BeanDefinitionRegistry configBeanDefinitions) {
|
||||
|
||||
ConfigurationParser parser = createConfigurationParser();
|
||||
|
||||
for(String beanName : configBeanDefinitions.getBeanDefinitionNames()) {
|
||||
BeanDefinition beanDef = configBeanDefinitions.getBeanDefinition(beanName);
|
||||
String className = beanDef.getBeanClassName();
|
||||
|
||||
parser.parse(className, beanName);
|
||||
}
|
||||
|
||||
return parser.getConfigurationModel();
|
||||
}
|
||||
|
||||
private BeanDefinitionRegistry renderModelAsBeanDefinitions(ConfigurationModel configModel) {
|
||||
// read the model and create bean definitions based on its content
|
||||
return new ConfigurationModelBeanDefinitionReader().loadBeanDefinitions(configModel);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import org.apache.commons.logging.LogFactory;
|
|||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
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.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
|
|
@ -33,6 +32,7 @@ import org.springframework.config.java.Configuration;
|
|||
import org.springframework.config.java.ConfigurationModel;
|
||||
import org.springframework.config.java.MalformedConfigurationException;
|
||||
import org.springframework.config.java.UsageError;
|
||||
import org.springframework.config.java.ext.Bean;
|
||||
import org.springframework.config.java.internal.enhancement.ConfigurationEnhancer;
|
||||
import org.springframework.config.java.internal.parsing.ConfigurationParser;
|
||||
import org.springframework.core.Ordered;
|
||||
|
|
@ -46,11 +46,23 @@ import org.springframework.util.StringUtils;
|
|||
/**
|
||||
* {@link BeanFactoryPostProcessor} used for bootstrapping processing of
|
||||
* {@link Configuration @Configuration} classes.
|
||||
* <p>
|
||||
* Registered by default when using {@literal <context:annotation-config/>} or
|
||||
* {@literal <context:component-scan/>}. Otherwise, may be declared manually as
|
||||
* with any other BeanFactoryPostProcessor.
|
||||
* <p>
|
||||
* This post processor is {@link Ordered#HIGHEST_PRECEDENCE} as it's important
|
||||
* that any {@link Bean} methods declared in Configuration classes have their
|
||||
* respective bean definitions registered before any other BeanFactoryPostProcessor
|
||||
* executes.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ConfigurationPostProcessor extends AbstractConfigurationClassProcessor
|
||||
implements Ordered, BeanFactoryPostProcessor {
|
||||
public class ConfigurationClassPostProcessor extends AbstractConfigurationClassProcessor
|
||||
implements Ordered, BeanFactoryPostProcessor {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ConfigurationPostProcessor.class);
|
||||
private static final Log logger = LogFactory.getLog(ConfigurationClassPostProcessor.class);
|
||||
|
||||
/**
|
||||
* A well-known class in the CGLIB API used when testing to see if CGLIB
|
||||
|
|
@ -68,8 +80,7 @@ public class ConfigurationPostProcessor extends AbstractConfigurationClassProces
|
|||
|
||||
|
||||
/**
|
||||
* @return the order in which this {@link BeanPostProcessor} will be executed. Returns
|
||||
* {@link Ordered#HIGHEST_PRECEDENCE}.
|
||||
* @return {@link Ordered#HIGHEST_PRECEDENCE}.
|
||||
*/
|
||||
public int getOrder() {
|
||||
return Ordered.HIGHEST_PRECEDENCE;
|
||||
|
|
@ -95,7 +106,7 @@ public class ConfigurationPostProcessor extends AbstractConfigurationClassProces
|
|||
|
||||
/**
|
||||
* @return a ConfigurationParser that uses the enclosing BeanFactory's
|
||||
* classLoader to load all Configuration class artifacts.
|
||||
* ClassLoader to load all Configuration class artifacts.
|
||||
*/
|
||||
@Override
|
||||
protected ConfigurationParser createConfigurationParser() {
|
||||
|
|
@ -103,7 +114,8 @@ public class ConfigurationPostProcessor extends AbstractConfigurationClassProces
|
|||
}
|
||||
|
||||
/**
|
||||
* @return map of all non-abstract {@link BeanDefinition}s in the enclosing {@link #beanFactory}
|
||||
* @return map of all non-abstract {@link BeanDefinition}s in the
|
||||
* enclosing {@link #beanFactory}
|
||||
*/
|
||||
@Override
|
||||
protected BeanDefinitionRegistry getConfigurationBeanDefinitions(boolean includeAbstractBeanDefs) {
|
||||
|
|
@ -14,17 +14,17 @@ import org.springframework.config.java.ext.Bean;
|
|||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ConfigurationPostProcessor}
|
||||
* Unit tests for {@link ConfigurationClassPostProcessor}
|
||||
*
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class ConfigurationPostProcessorTests {
|
||||
|
||||
private static final String ORIG_CGLIB_TEST_CLASS = ConfigurationPostProcessor.CGLIB_TEST_CLASS;
|
||||
private static final String ORIG_CGLIB_TEST_CLASS = ConfigurationClassPostProcessor.CGLIB_TEST_CLASS;
|
||||
private static final String BOGUS_CGLIB_TEST_CLASS = "a.bogus.class";
|
||||
|
||||
/**
|
||||
* CGLIB is an optional dependency for Core Spring. If users attempt
|
||||
* CGLIB is an optional dependency for Spring. If users attempt
|
||||
* to use {@link Configuration} classes, they'll need it on the classpath;
|
||||
* if Configuration classes are present in the bean factory and CGLIB
|
||||
* is not present, an instructive exception should be thrown.
|
||||
|
|
@ -39,17 +39,17 @@ public class ConfigurationPostProcessorTests {
|
|||
|
||||
factory.registerBeanDefinition("config1", rootBeanDefinition(Config.class).getBeanDefinition());
|
||||
|
||||
ConfigurationPostProcessor cpp = new ConfigurationPostProcessor();
|
||||
ConfigurationClassPostProcessor cpp = new ConfigurationClassPostProcessor();
|
||||
|
||||
// temporarily set the cglib test class to something bogus
|
||||
ConfigurationPostProcessor.CGLIB_TEST_CLASS = BOGUS_CGLIB_TEST_CLASS;
|
||||
ConfigurationClassPostProcessor.CGLIB_TEST_CLASS = BOGUS_CGLIB_TEST_CLASS;
|
||||
|
||||
try {
|
||||
cpp.postProcessBeanFactory(factory);
|
||||
} catch (RuntimeException ex) {
|
||||
assertTrue(ex.getMessage().contains("CGLIB is required to process @Configuration classes"));
|
||||
} finally {
|
||||
ConfigurationPostProcessor.CGLIB_TEST_CLASS = ORIG_CGLIB_TEST_CLASS;
|
||||
ConfigurationClassPostProcessor.CGLIB_TEST_CLASS = ORIG_CGLIB_TEST_CLASS;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ public class ConfigurationPostProcessorTests {
|
|||
* of {@link Configuration} classes.
|
||||
*
|
||||
* This test will fail if any CGLIB classes are classloaded before the call
|
||||
* to {@link ConfigurationPostProcessor#enhanceConfigurationClasses}
|
||||
* to {@link ConfigurationClassPostProcessor#enhanceConfigurationClasses}
|
||||
*/
|
||||
@Test
|
||||
public void testCglibClassesAreLoadedJustInTimeForEnhancement() throws Exception {
|
||||
|
|
@ -93,7 +93,7 @@ public class ConfigurationPostProcessorTests {
|
|||
* Enhanced {@link Configuration} classes are only necessary for respecting
|
||||
* certain bean semantics, like singleton-scoping, scoped proxies, etc.
|
||||
*
|
||||
* Technically, {@link ConfigurationPostProcessor} could fail to enhance the
|
||||
* Technically, {@link ConfigurationClassPostProcessor} could fail to enhance the
|
||||
* registered Configuration classes, and many use cases would still work.
|
||||
* Certain cases, however, like inter-bean singleton references would not.
|
||||
* We test for such a case below, and in doing so prove that enhancement is
|
||||
|
|
@ -104,7 +104,7 @@ public class ConfigurationPostProcessorTests {
|
|||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
beanFactory.registerBeanDefinition("config",
|
||||
rootBeanDefinition(SingletonBeanConfig.class).getBeanDefinition());
|
||||
new ConfigurationPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
Foo foo = (Foo) beanFactory.getBean("foo");
|
||||
Bar bar = (Bar) beanFactory.getBean("bar");
|
||||
assertThat(foo, sameInstance(bar.foo));
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
<context:annotation-config/>
|
||||
|
||||
<bean class="org.springframework.config.java.support.ConfigurationPostProcessor"/>
|
||||
<bean class="org.springframework.config.java.support.ConfigurationClassPostProcessor"/>
|
||||
|
||||
<bean class="test.basic.AutowiredConfigurationTests$AutowiredConfig"/>
|
||||
<bean class="test.basic.AutowiredConfigurationTests$ColorConfig"/>
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
|||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.config.java.Configuration;
|
||||
import org.springframework.config.java.MalformedConfigurationException;
|
||||
import org.springframework.config.java.Scopes;
|
||||
import org.springframework.config.java.StandardScopes;
|
||||
import org.springframework.config.java.ext.Bean;
|
||||
import org.springframework.config.java.support.ConfigurationPostProcessor;
|
||||
import org.springframework.config.java.support.ConfigurationClassPostProcessor;
|
||||
|
||||
import test.beans.ITestBean;
|
||||
import test.beans.TestBean;
|
||||
|
|
@ -24,7 +24,7 @@ public class BasicTests {
|
|||
/**
|
||||
* Creates a new {@link BeanFactory}, populates it with a {@link BeanDefinition} for
|
||||
* each of the given {@link Configuration} <var>configClasses</var>, and then
|
||||
* post-processes the factory using JavaConfig's {@link ConfigurationPostProcessor}.
|
||||
* post-processes the factory using JavaConfig's {@link ConfigurationClassPostProcessor}.
|
||||
* When complete, the factory is ready to service requests for any {@link Bean} methods
|
||||
* declared by <var>configClasses</var>.
|
||||
*
|
||||
|
|
@ -42,7 +42,7 @@ public class BasicTests {
|
|||
.getBeanDefinition());
|
||||
}
|
||||
|
||||
new ConfigurationPostProcessor().postProcessBeanFactory(factory);
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(factory);
|
||||
|
||||
factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ public class BasicTests {
|
|||
return bar;
|
||||
}
|
||||
|
||||
@Bean(scope = Scopes.PROTOTYPE)
|
||||
@Bean(scope = StandardScopes.PROTOTYPE)
|
||||
public TestBean baz() {
|
||||
return new TestBean("bar");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
<context:annotation-config/>
|
||||
|
||||
<bean class="org.springframework.config.java.support.ConfigurationPostProcessor"/>
|
||||
<bean class="org.springframework.config.java.support.ConfigurationClassPostProcessor"/>
|
||||
|
||||
<bean class="test.basic.AutowiredConfigurationTests$ValueConfig"/>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue