Refactoring and repackaging
This commit is contained in:
parent
d4fdad2202
commit
6deb1acab4
|
@ -67,8 +67,7 @@ import org.springframework.config.java.Validator;
|
|||
@Documented
|
||||
@Factory(registrarType=BeanRegistrar.class,
|
||||
callbackType=BeanMethodInterceptor.class,
|
||||
validatorTypes={BeanValidator.class,
|
||||
IllegalBeanOverrideValidator.class})
|
||||
validatorTypes={BeanValidator.class, IllegalBeanOverrideValidator.class})
|
||||
public @interface Bean {
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,23 +15,17 @@
|
|||
*/
|
||||
package org.springframework.config.java.internal.factory.support;
|
||||
|
||||
import static org.springframework.config.java.Util.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
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.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.core.io.ClassPathResource;
|
||||
|
||||
|
||||
|
@ -44,17 +38,17 @@ import org.springframework.core.io.ClassPathResource;
|
|||
*
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AsmJavaConfigBeanDefinitionReader {
|
||||
public class ConfigurationClassBeanDefinitionReader {
|
||||
|
||||
private final ConfigurationModelBeanDefinitionReader modelBeanDefinitionReader;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AsmJavaConfigBeanDefinitionReader}.
|
||||
* Creates a new {@link ConfigurationClassBeanDefinitionReader}.
|
||||
*
|
||||
* @param registry {@link BeanDefinitionRegistry} into which new bean definitions will be
|
||||
* @param beanFactory {@link DefaultListableBeanFactory} into which new bean definitions will be
|
||||
* registered as they are read from Configuration classes.
|
||||
*/
|
||||
public AsmJavaConfigBeanDefinitionReader(DefaultListableBeanFactory beanFactory) {
|
||||
public ConfigurationClassBeanDefinitionReader(DefaultListableBeanFactory beanFactory) {
|
||||
this.modelBeanDefinitionReader = new ConfigurationModelBeanDefinitionReader(beanFactory);
|
||||
}
|
||||
|
||||
|
@ -64,13 +58,10 @@ public class AsmJavaConfigBeanDefinitionReader {
|
|||
* supplied during construction.
|
||||
*/
|
||||
public int loadBeanDefinitions(ConfigurationModel model, Map<String, ClassPathResource> configClassResources) throws BeanDefinitionStoreException {
|
||||
ConfigurationParser parser = new AsmConfigurationParser(model);
|
||||
ConfigurationParser parser = new ConfigurationParser(model);
|
||||
|
||||
for (String id : configClassResources.keySet()) {
|
||||
String resourcePath = configClassResources.get(id).getPath();
|
||||
ClassReader configClassReader = AsmUtils.newClassReader(getClassAsStream(resourcePath));
|
||||
parser.parse(configClassReader, id);
|
||||
}
|
||||
for (String id : configClassResources.keySet())
|
||||
parser.parse(configClassResources.get(id), id);
|
||||
|
||||
ArrayList<UsageError> errors = new ArrayList<UsageError>();
|
||||
model.validate(errors);
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.config.java.internal.parsing.asm;
|
||||
package org.springframework.config.java.internal.parsing;
|
||||
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.config.java.internal.parsing.asm;
|
||||
package org.springframework.config.java.internal.parsing;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
|
@ -13,11 +13,11 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.config.java.internal.parsing.asm;
|
||||
package org.springframework.config.java.internal.parsing;
|
||||
|
||||
import static org.springframework.config.java.Util.*;
|
||||
import static org.springframework.config.java.internal.parsing.asm.AsmUtils.*;
|
||||
import static org.springframework.config.java.internal.parsing.asm.MutableAnnotationUtils.*;
|
||||
import static org.springframework.config.java.internal.parsing.AsmUtils.*;
|
||||
import static org.springframework.config.java.internal.parsing.MutableAnnotationUtils.*;
|
||||
import static org.springframework.util.ClassUtils.*;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
|
@ -13,10 +13,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.config.java.internal.parsing.asm;
|
||||
package org.springframework.config.java.internal.parsing;
|
||||
|
||||
import static org.springframework.config.java.Util.*;
|
||||
import static org.springframework.config.java.internal.parsing.asm.MutableAnnotationUtils.*;
|
||||
import static org.springframework.config.java.internal.parsing.MutableAnnotationUtils.*;
|
||||
import static org.springframework.util.ClassUtils.*;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
|
@ -15,46 +15,65 @@
|
|||
*/
|
||||
package org.springframework.config.java.internal.parsing;
|
||||
|
||||
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.config.java.Configuration;
|
||||
import org.springframework.config.java.ConfigurationClass;
|
||||
import org.springframework.config.java.ConfigurationModel;
|
||||
import org.springframework.config.java.Util;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
|
||||
/**
|
||||
* Parses a {@link Configuration} class definition, usually into a {@link ConfigurationModel}.
|
||||
* Parses a {@link Configuration} class definition, populating a {@link ConfigurationModel}.
|
||||
* This ASM-based implementation avoids reflection and eager classloading in order to
|
||||
* interoperate effectively with tooling (Spring IDE) and OSGi environments.
|
||||
* <p>
|
||||
* This interface aids in separating the process of reading a class file (via reflection, ASM, etc)
|
||||
* from the process of registering bean definitions based on the content of that class.
|
||||
* This class helps separate the concern of parsing the structure of a Configuration class
|
||||
* from the concern of registering {@link BeanDefinition} objects based on the content of
|
||||
* that model.
|
||||
*
|
||||
* @see org.springframework.config.java.internal.parsing.asm.AsmConfigurationParser
|
||||
* @see org.springframework.config.java.ConfigurationModel
|
||||
* @see org.springframework.config.java.internal.factory.support.ConfigurationModelBeanDefinitionReader
|
||||
*
|
||||
*
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public interface ConfigurationParser {
|
||||
*/
|
||||
public class ConfigurationParser {
|
||||
|
||||
/**
|
||||
* Parse the Configuration object represented by <var>configurationSource.</var>
|
||||
*
|
||||
* @param configurationSource representation of a Configuration class, may be java.lang.Class,
|
||||
* ASM representation or otherwise
|
||||
*
|
||||
* @see org.springframework.config.java.Configuration
|
||||
* Model to be populated during calls to {@link #parse(Object, String)}
|
||||
*/
|
||||
void parse(Object configurationSource);
|
||||
private final ConfigurationModel model;
|
||||
|
||||
/**
|
||||
* Optionally propagate a custom name for this <var>configurationSource</var>. Usually this id
|
||||
* corresponds to the name of a Configuration bean as declared in a beans XML.
|
||||
* Creates a new parser instance that will be used to populate <var>model</var>.
|
||||
*
|
||||
* @param configurationSource representation of a Configuration class, may be java.lang.Class,
|
||||
* ASM representation or otherwise
|
||||
* @param configurationId name of this configuration class, probably corresponding to a
|
||||
* bean id
|
||||
*
|
||||
* @see org.springframework.config.java.Configuration
|
||||
* @see org.springframework.config.java.process.ConfigurationPostProcessor
|
||||
* @param model model to be populated by each successive call to {@link #parse(Object, String)}
|
||||
*/
|
||||
void parse(Object configurationSource, String configurationId);
|
||||
public ConfigurationParser(ConfigurationModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@link Configuration @Configuration} class encapsulated by
|
||||
* <var>configurationSource</var>.
|
||||
*
|
||||
* @param configurationSource reader for Configuration class being parsed
|
||||
* @param configurationId may be null, but if populated represents the bean id
|
||||
* (assumes that this configuration class was configured via XML)
|
||||
*/
|
||||
public void parse(ClassPathResource resource, String configurationId) {
|
||||
|
||||
String resourcePath = resource.getPath();
|
||||
ClassReader configClassReader = AsmUtils.newClassReader(Util.getClassAsStream(resourcePath));
|
||||
|
||||
ConfigurationClass configClass = new ConfigurationClass();
|
||||
configClass.setBeanName(configurationId);
|
||||
|
||||
configClassReader.accept(new ConfigurationClassVisitor(configClass, model), false);
|
||||
model.add(configClass);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.config.java.internal.parsing.asm;
|
||||
package org.springframework.config.java.internal.parsing;
|
||||
|
||||
|
||||
/**
|
|
@ -13,10 +13,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.config.java.internal.parsing.asm;
|
||||
package org.springframework.config.java.internal.parsing;
|
||||
|
||||
import static org.springframework.config.java.Util.*;
|
||||
import static org.springframework.config.java.internal.parsing.asm.MutableAnnotationUtils.*;
|
||||
import static org.springframework.config.java.internal.parsing.MutableAnnotationUtils.*;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Array;
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.config.java.internal.parsing.asm;
|
||||
package org.springframework.config.java.internal.parsing;
|
||||
|
||||
import static java.lang.String.*;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.*;
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.config.java.internal.parsing.asm;
|
||||
package org.springframework.config.java.internal.parsing;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Proxy;
|
|
@ -13,10 +13,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.config.java.internal.parsing.asm;
|
||||
package org.springframework.config.java.internal.parsing;
|
||||
|
||||
import static org.springframework.config.java.Util.*;
|
||||
import static org.springframework.config.java.internal.parsing.asm.MutableAnnotationUtils.*;
|
||||
import static org.springframework.config.java.internal.parsing.MutableAnnotationUtils.*;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
* 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.parsing.asm;
|
||||
|
||||
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
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.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* ASM-based implementation of {@link ConfigurationParser}. Avoids reflection and eager classloading
|
||||
* in order to interoperate effectively with tooling (Spring IDE).
|
||||
*
|
||||
* @see org.springframework.config.java.model.AsmConfigurationParserTests
|
||||
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class AsmConfigurationParser implements ConfigurationParser {
|
||||
|
||||
/**
|
||||
* Model to be populated during calls to {@link #parse(Object)}
|
||||
*/
|
||||
private final ConfigurationModel model;
|
||||
|
||||
/**
|
||||
* Creates a new parser instance that will be used to populate <var>model</var>.
|
||||
*
|
||||
* @param model model to be populated by each successive call to {@link #parse(Object)}
|
||||
*/
|
||||
public AsmConfigurationParser(ConfigurationModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience implementation, delegates to {@link #parse(Object, String)},
|
||||
* passing in {@code null} for the configurationId.
|
||||
*
|
||||
* @param configurationSource must be an ASM {@link ClassReader}
|
||||
*/
|
||||
public void parse(Object configurationSource) {
|
||||
parse(configurationSource, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@link Configuration @Configuration} class encapsulated by
|
||||
* <var>configurationSource</var>.
|
||||
*
|
||||
* @param configurationSource must be an ASM {@link ClassReader}
|
||||
* @param configurationId may be null, but if populated represents the bean id
|
||||
* (assumes that this configuration class was configured via XML)
|
||||
*/
|
||||
public void parse(Object configurationSource, String configurationId) {
|
||||
Assert.isInstanceOf(ClassReader.class, configurationSource,
|
||||
"configurationSource must be an ASM ClassReader");
|
||||
|
||||
ConfigurationClass configClass = new ConfigurationClass();
|
||||
configClass.setBeanName(configurationId);
|
||||
|
||||
parse((ClassReader) configurationSource, configClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kicks off visiting <var>configClass</var> with {@link ConfigurationClassVisitor}
|
||||
*/
|
||||
private void parse(ClassReader reader, ConfigurationClass configClass) {
|
||||
reader.accept(new ConfigurationClassVisitor(configClass, model), false);
|
||||
model.add(configClass);
|
||||
}
|
||||
|
||||
}
|
|
@ -17,6 +17,7 @@ package org.springframework.config.java.internal.process;
|
|||
|
||||
import static org.springframework.config.java.Util.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
@ -29,8 +30,12 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
|||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
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.enhancement.ConfigurationEnhancer;
|
||||
import org.springframework.config.java.internal.factory.support.AsmJavaConfigBeanDefinitionReader;
|
||||
import org.springframework.config.java.internal.factory.support.ConfigurationClassBeanDefinitionReader;
|
||||
import org.springframework.config.java.internal.factory.support.ConfigurationModelBeanDefinitionReader;
|
||||
import org.springframework.config.java.internal.parsing.ConfigurationParser;
|
||||
import org.springframework.config.java.process.ConfigurationPostProcessor;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
@ -46,19 +51,21 @@ public class InternalConfigurationPostProcessor implements BeanFactoryPostProces
|
|||
* to parse and enhance them. Also registers any {@link BeanPostProcessor} objects
|
||||
* necessary to fulfill JavaConfig requirements.
|
||||
*/
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
if(!(beanFactory instanceof DefaultListableBeanFactory))
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory clBeanFactory) throws BeansException {
|
||||
if(!(clBeanFactory instanceof DefaultListableBeanFactory))
|
||||
throw new IllegalStateException("beanFactory must be of type "
|
||||
+ DefaultListableBeanFactory.class.getSimpleName());
|
||||
|
||||
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) clBeanFactory;
|
||||
|
||||
ConfigurationModel model = new ConfigurationModel();
|
||||
|
||||
parseAnyConfigurationClasses(beanFactory, model);
|
||||
|
||||
enhanceAnyConfigurationClasses((DefaultListableBeanFactory) beanFactory, model);
|
||||
enhanceAnyConfigurationClasses(beanFactory, model);
|
||||
}
|
||||
|
||||
private void parseAnyConfigurationClasses(ConfigurableListableBeanFactory beanFactory, ConfigurationModel model) {
|
||||
private void parseAnyConfigurationClasses(DefaultListableBeanFactory beanFactory, ConfigurationModel model) {
|
||||
|
||||
// linked map is important for maintaining predictable ordering of configuration classes.
|
||||
// this is important in bean / value override situations.
|
||||
|
@ -75,7 +82,18 @@ public class InternalConfigurationPostProcessor implements BeanFactoryPostProces
|
|||
}
|
||||
}
|
||||
|
||||
beanDefinitionReader(beanFactory).loadBeanDefinitions(model, configClassResources);
|
||||
ConfigurationModelBeanDefinitionReader modelBeanDefinitionReader = new ConfigurationModelBeanDefinitionReader(beanFactory);
|
||||
ConfigurationParser parser = new ConfigurationParser(model);
|
||||
|
||||
for (String id : configClassResources.keySet())
|
||||
parser.parse(configClassResources.get(id), id);
|
||||
|
||||
ArrayList<UsageError> errors = new ArrayList<UsageError>();
|
||||
model.validate(errors);
|
||||
if (errors.size() > 0)
|
||||
throw new MalformedJavaConfigurationException(errors.toArray(new UsageError[] { }));
|
||||
|
||||
modelBeanDefinitionReader.loadBeanDefinitions(model);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,7 +114,6 @@ public class InternalConfigurationPostProcessor implements BeanFactoryPostProces
|
|||
for (String beanName : beanFactory.getBeanDefinitionNames()) {
|
||||
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
|
||||
|
||||
// is the beanDef marked as representing a configuration class?
|
||||
if (!isConfigClass(beanDef))
|
||||
continue;
|
||||
|
||||
|
@ -117,15 +134,6 @@ public class InternalConfigurationPostProcessor implements BeanFactoryPostProces
|
|||
logger.warn("Found no @Configuration class BeanDefinitions within " + beanFactory);
|
||||
}
|
||||
|
||||
private AsmJavaConfigBeanDefinitionReader beanDefinitionReader(ConfigurableListableBeanFactory beanFactory) {
|
||||
// reader requires DefaultListableBeanFactory for it's registerBeanDefinition() method
|
||||
if(!(beanFactory instanceof DefaultListableBeanFactory))
|
||||
throw new IllegalStateException("beanFactory must be of type "
|
||||
+ DefaultListableBeanFactory.class.getSimpleName());
|
||||
|
||||
return new AsmJavaConfigBeanDefinitionReader((DefaultListableBeanFactory)beanFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the class for <var>beanDef</var> is a {@link Configuration}-annotated
|
||||
* class. Returns false if <var>beanDef</var> has no class specified.
|
||||
|
@ -133,7 +141,7 @@ public class InternalConfigurationPostProcessor implements BeanFactoryPostProces
|
|||
* Note: the classloading used within should not be problematic or interfere with tooling in any
|
||||
* way. BeanFactoryPostProcessing happens only during actual runtime processing via
|
||||
* {@link JavaConfigApplicationContext} or via XML using {@link ConfigurationPostProcessor}. In
|
||||
* any case, tooling (Spring IDE) will use {@link AsmJavaConfigBeanDefinitionReader}directly,
|
||||
* any case, tooling (Spring IDE) will use {@link ConfigurationClassBeanDefinitionReader}directly,
|
||||
* thus never encountering this classloading. Should this become problematic, it would not be
|
||||
* too difficult to replace the following with ASM logic that traverses the class hierarchy in
|
||||
* order to find whether the class is directly or indirectly annotated with
|
||||
|
|
Loading…
Reference in New Issue