parent
3482c170e0
commit
481aeeec98
|
@ -185,8 +185,7 @@ class ConfigurationClassParser {
|
||||||
|
|
||||||
|
|
||||||
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
|
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
|
||||||
|
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
|
||||||
if (conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,9 +218,7 @@ class ConfigurationClassParser {
|
||||||
* @param sourceClass a source class
|
* @param sourceClass a source class
|
||||||
* @return the superclass, {@code null} if none found or previously processed
|
* @return the superclass, {@code null} if none found or previously processed
|
||||||
*/
|
*/
|
||||||
protected final SourceClass doProcessConfigurationClass(
|
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
|
||||||
ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
|
|
||||||
|
|
||||||
// recursively process any member (nested) classes first
|
// recursively process any member (nested) classes first
|
||||||
processMemberClasses(configClass, sourceClass);
|
processMemberClasses(configClass, sourceClass);
|
||||||
|
|
||||||
|
@ -350,18 +347,15 @@ class ConfigurationClassParser {
|
||||||
* meta-annotations it is valid to have several {@code @Import}s declared with
|
* meta-annotations it is valid to have several {@code @Import}s declared with
|
||||||
* different values, the usual process or returning values from the first
|
* different values, the usual process or returning values from the first
|
||||||
* meta-annotation on a class is not sufficient.
|
* meta-annotation on a class is not sufficient.
|
||||||
* <p>
|
* <p>For example, it is common for a {@code @Configuration} class to declare direct
|
||||||
* For example, it is common for a {@code @Configuration} class to declare direct
|
|
||||||
* {@code @Import}s in addition to meta-imports originating from an {@code @Enable}
|
* {@code @Import}s in addition to meta-imports originating from an {@code @Enable}
|
||||||
* annotation.
|
* annotation.
|
||||||
*
|
|
||||||
* @param sourceClass the class to search
|
* @param sourceClass the class to search
|
||||||
* @param imports the imports collected so far
|
* @param imports the imports collected so far
|
||||||
* @param visited used to track visited classes to prevent infinite recursion
|
* @param visited used to track visited classes to prevent infinite recursion
|
||||||
* @throws IOException if there is any problem reading metadata from the named class
|
* @throws IOException if there is any problem reading metadata from the named class
|
||||||
*/
|
*/
|
||||||
private void collectImports(SourceClass sourceClass, Set<SourceClass> imports,
|
private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited) throws IOException {
|
||||||
Set<SourceClass> visited) throws IOException {
|
|
||||||
try {
|
try {
|
||||||
if (visited.add(sourceClass)) {
|
if (visited.add(sourceClass)) {
|
||||||
for (SourceClass annotation : sourceClass.getAnnotations()) {
|
for (SourceClass annotation : sourceClass.getAnnotations()) {
|
||||||
|
@ -392,9 +386,9 @@ class ConfigurationClassParser {
|
||||||
this.deferredImportSelectors.clear();
|
this.deferredImportSelectors.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processImports(ConfigurationClass configClass,
|
private void processImports(ConfigurationClass configClass, Collection<SourceClass> sourceClasses, boolean checkForCircularImports)
|
||||||
Collection<SourceClass> sourceClasses, boolean checkForCircularImports)
|
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
if(sourceClasses.isEmpty()) {
|
if(sourceClasses.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -494,8 +488,7 @@ class ConfigurationClassParser {
|
||||||
/**
|
/**
|
||||||
* Factory method to obtain a {@link SourceClass} from a {@link ConfigurationClass}.
|
* Factory method to obtain a {@link SourceClass} from a {@link ConfigurationClass}.
|
||||||
*/
|
*/
|
||||||
public SourceClass asSourceClass(ConfigurationClass configurationClass)
|
public SourceClass asSourceClass(ConfigurationClass configurationClass) throws IOException {
|
||||||
throws IOException {
|
|
||||||
try {
|
try {
|
||||||
AnnotationMetadata metadata = configurationClass.getMetadata();
|
AnnotationMetadata metadata = configurationClass.getMetadata();
|
||||||
if (metadata instanceof StandardAnnotationMetadata) {
|
if (metadata instanceof StandardAnnotationMetadata) {
|
||||||
|
@ -511,8 +504,7 @@ class ConfigurationClassParser {
|
||||||
/**
|
/**
|
||||||
* Factory method to obtain a {@link SourceClass} from a {@link Class}.
|
* Factory method to obtain a {@link SourceClass} from a {@link Class}.
|
||||||
*/
|
*/
|
||||||
public SourceClass asSourceClass(Class<?> classType)
|
public SourceClass asSourceClass(Class<?> classType) throws IOException, ClassNotFoundException {
|
||||||
throws ClassNotFoundException, IOException {
|
|
||||||
try {
|
try {
|
||||||
// Sanity test that we can read annotations, if not fall back to ASM
|
// Sanity test that we can read annotations, if not fall back to ASM
|
||||||
classType.getAnnotations();
|
classType.getAnnotations();
|
||||||
|
@ -526,10 +518,9 @@ class ConfigurationClassParser {
|
||||||
/**
|
/**
|
||||||
* Factory method to obtain {@link SourceClass}s from class names.
|
* Factory method to obtain {@link SourceClass}s from class names.
|
||||||
*/
|
*/
|
||||||
public Collection<SourceClass> asSourceClasses(String[] classNamess)
|
public Collection<SourceClass> asSourceClasses(String[] classNames) throws IOException, ClassNotFoundException {
|
||||||
throws ClassNotFoundException, IOException {
|
|
||||||
List<SourceClass> annotatedClasses = new ArrayList<SourceClass>();
|
List<SourceClass> annotatedClasses = new ArrayList<SourceClass>();
|
||||||
for (String className : classNamess) {
|
for (String className : classNames) {
|
||||||
annotatedClasses.add(asSourceClass(className));
|
annotatedClasses.add(asSourceClass(className));
|
||||||
}
|
}
|
||||||
return annotatedClasses;
|
return annotatedClasses;
|
||||||
|
@ -538,12 +529,10 @@ class ConfigurationClassParser {
|
||||||
/**
|
/**
|
||||||
* Factory method to obtain a {@link SourceClass} from a class name.
|
* Factory method to obtain a {@link SourceClass} from a class name.
|
||||||
*/
|
*/
|
||||||
public SourceClass asSourceClass(String className)
|
public SourceClass asSourceClass(String className) throws IOException, ClassNotFoundException {
|
||||||
throws ClassNotFoundException, IOException {
|
|
||||||
if (className.startsWith("java")) {
|
if (className.startsWith("java")) {
|
||||||
// Never use ASM for core java types
|
// Never use ASM for core java types
|
||||||
return new SourceClass(this.resourceLoader.getClassLoader().loadClass(
|
return new SourceClass(this.resourceLoader.getClassLoader().loadClass( className));
|
||||||
className));
|
|
||||||
}
|
}
|
||||||
return new SourceClass(this.metadataReaderFactory.getMetadataReader(className));
|
return new SourceClass(this.metadataReaderFactory.getMetadataReader(className));
|
||||||
}
|
}
|
||||||
|
@ -642,8 +631,7 @@ class ConfigurationClassParser {
|
||||||
|
|
||||||
private final AnnotationMetadata metadata;
|
private final AnnotationMetadata metadata;
|
||||||
|
|
||||||
|
public SourceClass(Object source) {
|
||||||
private SourceClass(Object source) {
|
|
||||||
this.source = source;
|
this.source = source;
|
||||||
if (source instanceof Class<?>) {
|
if (source instanceof Class<?>) {
|
||||||
this.metadata = new StandardAnnotationMetadata((Class<?>) source, true);
|
this.metadata = new StandardAnnotationMetadata((Class<?>) source, true);
|
||||||
|
@ -653,40 +641,42 @@ class ConfigurationClassParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final AnnotationMetadata getMetadata() {
|
||||||
|
return this.metadata;
|
||||||
|
}
|
||||||
|
|
||||||
public Class<?> loadClass() throws ClassNotFoundException {
|
public Class<?> loadClass() throws ClassNotFoundException {
|
||||||
if(source instanceof Class<?>) {
|
if (this.source instanceof Class<?>) {
|
||||||
return (Class<?>) source;
|
return (Class<?>) this.source;
|
||||||
}
|
}
|
||||||
String className = ((MetadataReader) source).getClassMetadata().getClassName();
|
String className = ((MetadataReader) source).getClassMetadata().getClassName();
|
||||||
return resourceLoader.getClassLoader().loadClass(className);
|
return resourceLoader.getClassLoader().loadClass(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAssignable(Class<?> clazz) throws IOException {
|
public boolean isAssignable(Class<?> clazz) throws IOException {
|
||||||
if (source instanceof Class) {
|
if (this.source instanceof Class) {
|
||||||
return clazz.isAssignableFrom((Class) source);
|
return clazz.isAssignableFrom((Class) this.source);
|
||||||
}
|
}
|
||||||
return new AssignableTypeFilter(clazz).match((MetadataReader) source,
|
return new AssignableTypeFilter(clazz).match((MetadataReader) this.source, metadataReaderFactory);
|
||||||
metadataReaderFactory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfigurationClass asConfigClass(ConfigurationClass importedBy)
|
public ConfigurationClass asConfigClass(ConfigurationClass importedBy) throws IOException {
|
||||||
throws IOException {
|
|
||||||
if (this.source instanceof Class<?>) {
|
if (this.source instanceof Class<?>) {
|
||||||
return new ConfigurationClass((Class<?>) this.source, importedBy);
|
return new ConfigurationClass((Class<?>) this.source, importedBy);
|
||||||
}
|
}
|
||||||
return new ConfigurationClass((MetadataReader) source, importedBy);
|
return new ConfigurationClass((MetadataReader) this.source, importedBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<SourceClass> getMemberClasses() throws IOException {
|
public Collection<SourceClass> getMemberClasses() throws IOException {
|
||||||
List<SourceClass> members = new ArrayList<SourceClass>();
|
List<SourceClass> members = new ArrayList<SourceClass>();
|
||||||
if (source instanceof Class<?>) {
|
if (this.source instanceof Class<?>) {
|
||||||
Class<?> sourceClass = (Class<?>) source;
|
Class<?> sourceClass = (Class<?>) this.source;
|
||||||
for (Class<?> declaredClass : sourceClass.getDeclaredClasses()) {
|
for (Class<?> declaredClass : sourceClass.getDeclaredClasses()) {
|
||||||
try {
|
try {
|
||||||
members.add(asSourceClass(declaredClass));
|
members.add(asSourceClass(declaredClass));
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException e) {
|
catch (ClassNotFoundException ex) {
|
||||||
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -696,34 +686,34 @@ class ConfigurationClassParser {
|
||||||
try {
|
try {
|
||||||
members.add(asSourceClass(memberClassName));
|
members.add(asSourceClass(memberClassName));
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException e) {
|
catch (ClassNotFoundException ex) {
|
||||||
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return members;
|
return members;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourceClass getSuperClass() throws ClassNotFoundException, IOException {
|
public SourceClass getSuperClass() throws IOException, ClassNotFoundException {
|
||||||
if (source instanceof Class<?>) {
|
if (this.source instanceof Class<?>) {
|
||||||
return asSourceClass(((Class<?>) source).getSuperclass());
|
return asSourceClass(((Class<?>) this.source).getSuperclass());
|
||||||
}
|
}
|
||||||
return asSourceClass(((MetadataReader) source).getClassMetadata().getSuperClassName());
|
return asSourceClass(((MetadataReader) this.source).getClassMetadata().getSuperClassName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<SourceClass> getAnnotations() throws ClassNotFoundException, IOException {
|
public Set<SourceClass> getAnnotations() throws IOException, ClassNotFoundException {
|
||||||
Set<SourceClass> annotations = new LinkedHashSet<SourceClass>();
|
Set<SourceClass> annotations = new LinkedHashSet<SourceClass>();
|
||||||
for(String annotation : getMetadata().getAnnotationTypes()) {
|
for (String annotation : this.metadata.getAnnotationTypes()) {
|
||||||
annotations.add(getRelated(annotation));
|
annotations.add(getRelated(annotation));
|
||||||
}
|
}
|
||||||
return annotations;
|
return annotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<SourceClass> getAnnotationAttributes(String annotationType,
|
public Collection<SourceClass> getAnnotationAttributes(String annotationType, String attribute)
|
||||||
String attribute) throws ClassNotFoundException, IOException {
|
throws IOException, ClassNotFoundException {
|
||||||
Map<String, Object> annotationAttributes = getMetadata().getAnnotationAttributes(
|
|
||||||
annotationType, true);
|
Map<String, Object> annotationAttributes = this.metadata.getAnnotationAttributes(annotationType, true);
|
||||||
if (annotationAttributes == null
|
if (annotationAttributes == null || !annotationAttributes.containsKey(attribute)) {
|
||||||
|| !annotationAttributes.containsKey(attribute)) {
|
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
String[] classNames = (String[]) annotationAttributes.get(attribute);
|
String[] classNames = (String[]) annotationAttributes.get(attribute);
|
||||||
|
@ -734,45 +724,33 @@ class ConfigurationClassParser {
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SourceClass getRelated(String className) throws IOException,
|
private SourceClass getRelated(String className) throws IOException, ClassNotFoundException {
|
||||||
ClassNotFoundException {
|
if (this.source instanceof Class<?>) {
|
||||||
if (source instanceof Class<?>) {
|
|
||||||
try {
|
try {
|
||||||
Class<?> clazz = resourceLoader.getClassLoader().loadClass(className);
|
Class<?> clazz = resourceLoader.getClassLoader().loadClass(className);
|
||||||
return asSourceClass(clazz);
|
return asSourceClass(clazz);
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException ex) {
|
catch (ClassNotFoundException ex) {
|
||||||
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return asSourceClass(className);
|
return asSourceClass(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AnnotationMetadata getMetadata() {
|
@Override
|
||||||
return this.metadata;
|
public boolean equals(Object other) {
|
||||||
|
return (this == other || (other instanceof SourceClass &&
|
||||||
|
this.metadata.getClassName().equals(((SourceClass) other).metadata.getClassName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return toString().hashCode();
|
return this.metadata.getClassName().hashCode();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj == this) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (obj instanceof SourceClass) {
|
|
||||||
return toString().equals(obj.toString());
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getMetadata().getClassName();
|
return this.metadata.getClassName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
import org.springframework.core.Conventions;
|
import org.springframework.core.Conventions;
|
||||||
|
@ -36,8 +37,6 @@ import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||||
*/
|
*/
|
||||||
abstract class ConfigurationClassUtils {
|
abstract class ConfigurationClassUtils {
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(ConfigurationClassUtils.class);
|
|
||||||
|
|
||||||
private static final String CONFIGURATION_CLASS_FULL = "full";
|
private static final String CONFIGURATION_CLASS_FULL = "full";
|
||||||
|
|
||||||
private static final String CONFIGURATION_CLASS_LITE = "lite";
|
private static final String CONFIGURATION_CLASS_LITE = "lite";
|
||||||
|
@ -45,6 +44,8 @@ abstract class ConfigurationClassUtils {
|
||||||
private static final String CONFIGURATION_CLASS_ATTRIBUTE =
|
private static final String CONFIGURATION_CLASS_ATTRIBUTE =
|
||||||
Conventions.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass");
|
Conventions.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass");
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(ConfigurationClassUtils.class);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the given bean definition is a candidate for a configuration class,
|
* Check whether the given bean definition is a candidate for a configuration class,
|
||||||
|
@ -92,7 +93,7 @@ abstract class ConfigurationClassUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isConfigurationCandidate(AnnotationMetadata metadata) {
|
public static boolean isConfigurationCandidate(AnnotationMetadata metadata) {
|
||||||
return isFullConfigurationCandidate(metadata) || isLiteConfigurationCandidate(metadata);
|
return (isFullConfigurationCandidate(metadata) || isLiteConfigurationCandidate(metadata));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) {
|
public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) {
|
||||||
|
@ -100,13 +101,10 @@ abstract class ConfigurationClassUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isLiteConfigurationCandidate(AnnotationMetadata metadata) {
|
public static boolean isLiteConfigurationCandidate(AnnotationMetadata metadata) {
|
||||||
if(metadata.isInterface()) {
|
// Do not consider an interface or an annotation...
|
||||||
return false; // do not consider an interface or an annotation
|
return (!metadata.isInterface() && (
|
||||||
|
metadata.isAnnotated(Import.class.getName()) || metadata.hasAnnotatedMethods(Bean.class.getName())));
|
||||||
}
|
}
|
||||||
return metadata.isAnnotated(Import.class.getName()) ||
|
|
||||||
metadata.hasAnnotatedMethods(Bean.class.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the given bean definition indicates a full @Configuration class.
|
* Determine whether the given bean definition indicates a full @Configuration class.
|
||||||
|
|
Loading…
Reference in New Issue