提交 2e7e9824 编写于 作者: C Chris Beams

+ Renamed Scopes -> StandardScopes

+ Renamed ConfigurationPostProcessor -> ConfigurationClassPostProcessor
+ JavaDoc and polish for AbstractConfigurationClassProcessor
上级 8610c0bc
......@@ -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.
......
/*
* 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
ConfigurationModel configModel = createConfigurationModelFor(configBeanDefs);
validateModel(configModel);
return configBeanDefs;
return renderModelAsBeanDefinitions(configModel);
}
private ConfigurationModel createConfigurationModelFor(BeanDefinitionRegistry configBeanDefinitions) {
// 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);
}
for(String beanName : configBeanDefinitions.getBeanDefinitionNames()) {
BeanDefinition beanDef = configBeanDefinitions.getBeanDefinition(beanName);
String className = beanDef.getBeanClassName();
parser.parse(className, beanName);
}
ConfigurationModel configModel = parser.getConfigurationModel();
return parser.getConfigurationModel();
}
private BeanDefinitionRegistry renderModelAsBeanDefinitions(ConfigurationModel configModel) {
// validate the ConfigurationModel
validateModel(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"/>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册