Browse Source

Polishing

pull/1998/head
Juergen Hoeller 7 years ago
parent
commit
f5e6c707ae
  1. 12
      spring-beans/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionWrapper.java
  2. 29
      spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
  3. 12
      spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java
  4. 5
      spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java
  5. 2
      spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java
  6. 10
      spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java
  7. 11
      spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java
  8. 8
      spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java
  9. 20
      spring-context/src/main/java/org/springframework/context/support/GenericApplicationContext.java
  10. 10
      spring-context/src/main/java/org/springframework/scripting/config/ScriptBeanDefinitionParser.java
  11. 154
      spring-context/src/test/java/org/springframework/context/annotation/AnnotationConfigApplicationContextTests.java
  12. 3
      spring-context/src/test/java/org/springframework/context/support/GenericApplicationContextTests.java

12
spring-beans/src/main/java/org/springframework/beans/factory/groovy/GroovyBeanDefinitionWrapper.java

@ -24,7 +24,6 @@ import groovy.lang.GroovyObjectSupport;
import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl; import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConstructorArgumentValues; import org.springframework.beans.factory.config.ConstructorArgumentValues;
@ -182,16 +181,16 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
AbstractBeanDefinition bd = getBeanDefinition(); AbstractBeanDefinition bd = getBeanDefinition();
if (AUTOWIRE.equals(property)) { if (AUTOWIRE.equals(property)) {
if ("byName".equals(newValue)) { if ("byName".equals(newValue)) {
bd.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME); bd.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
} }
else if ("byType".equals(newValue)) { else if ("byType".equals(newValue)) {
bd.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE); bd.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
} }
else if ("constructor".equals(newValue)) { else if ("constructor".equals(newValue)) {
bd.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR); bd.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
} }
else if (Boolean.TRUE.equals(newValue)) { else if (Boolean.TRUE.equals(newValue)) {
bd.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME); bd.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
} }
} }
// constructorArgs // constructorArgs
@ -211,8 +210,9 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
} }
// factoryMethod // factoryMethod
else if (FACTORY_METHOD.equals(property)) { else if (FACTORY_METHOD.equals(property)) {
if (newValue != null) if (newValue != null) {
bd.setFactoryMethodName(newValue.toString()); bd.setFactoryMethodName(newValue.toString());
}
} }
// initMethod // initMethod
else if (INIT_METHOD.equals(property)) { else if (INIT_METHOD.equals(property)) {

29
spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java

@ -154,10 +154,10 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
*/ */
private final NamedThreadLocal<String> currentlyCreatedBean = new NamedThreadLocal<>("Currently created bean"); private final NamedThreadLocal<String> currentlyCreatedBean = new NamedThreadLocal<>("Currently created bean");
/** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */ /** Cache of unfinished FactoryBean instances: FactoryBean name to BeanWrapper */
private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>(16); private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>(16);
/** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */ /** Cache of filtered PropertyDescriptors: bean Class to PropertyDescriptor array */
private final ConcurrentMap<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache = private final ConcurrentMap<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
new ConcurrentHashMap<>(256); new ConcurrentHashMap<>(256);
@ -1116,10 +1116,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
} }
} }
// Need to determine the constructor... // Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args); return autowireConstructor(beanName, mbd, ctors, args);
} }
@ -1309,25 +1308,21 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs); MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable. // Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs); autowireByName(beanName, mbd, bw, newPvs);
} }
// Add property values based on autowire by type if applicable. // Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs); autowireByType(beanName, mbd, bw, newPvs);
} }
pvs = newPvs; pvs = newPvs;
} }
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) { if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) { if (pvs == null) {
@ -1532,9 +1527,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
for (PropertyDescriptor pd : pds) { for (PropertyDescriptor pd : pds) {
if (pd.getWriteMethod() != null && !pvs.contains(pd.getName())) { if (pd.getWriteMethod() != null && !pvs.contains(pd.getName())) {
boolean isSimple = BeanUtils.isSimpleProperty(pd.getPropertyType()); boolean isSimple = BeanUtils.isSimpleProperty(pd.getPropertyType());
boolean unsatisfied = (dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_ALL) || boolean unsatisfied = (dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_ALL) ||
(isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_SIMPLE) || (isSimple && dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE) ||
(!isSimple && dependencyCheck == RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS); (!isSimple && dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
if (unsatisfied) { if (unsatisfied) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, pd.getName(), throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, pd.getName(),
"Set this property value or disable dependency checking for this bean."); "Set this property value or disable dependency checking for this bean.");
@ -1787,7 +1782,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
if (initMethod == null) { if (initMethod == null) {
if (mbd.isEnforceInitMethod()) { if (mbd.isEnforceInitMethod()) {
throw new BeanDefinitionValidationException("Couldn't find an init method named '" + throw new BeanDefinitionValidationException("Could not find an init method named '" +
initMethodName + "' on bean with name '" + beanName + "'"); initMethodName + "' on bean with name '" + beanName + "'");
} }
else { else {

12
spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -69,9 +69,7 @@ public class BeanDefinitionBuilder {
* @param instanceSupplier a callback for creating an instance of the bean * @param instanceSupplier a callback for creating an instance of the bean
* @since 5.0 * @since 5.0
*/ */
public static <T> BeanDefinitionBuilder genericBeanDefinition( public static <T> BeanDefinitionBuilder genericBeanDefinition(Class<T> beanClass, Supplier<T> instanceSupplier) {
@Nullable Class<T> beanClass, Supplier<T> instanceSupplier) {
BeanDefinitionBuilder builder = new BeanDefinitionBuilder(new GenericBeanDefinition()); BeanDefinitionBuilder builder = new BeanDefinitionBuilder(new GenericBeanDefinition());
builder.beanDefinition.setBeanClass(beanClass); builder.beanDefinition.setBeanClass(beanClass);
builder.beanDefinition.setInstanceSupplier(instanceSupplier); builder.beanDefinition.setInstanceSupplier(instanceSupplier);
@ -275,7 +273,7 @@ public class BeanDefinitionBuilder {
* Set the autowire mode for this definition. * Set the autowire mode for this definition.
*/ */
public BeanDefinitionBuilder setAutowireMode(int autowireMode) { public BeanDefinitionBuilder setAutowireMode(int autowireMode) {
beanDefinition.setAutowireMode(autowireMode); this.beanDefinition.setAutowireMode(autowireMode);
return this; return this;
} }
@ -283,7 +281,7 @@ public class BeanDefinitionBuilder {
* Set the depency check mode for this definition. * Set the depency check mode for this definition.
*/ */
public BeanDefinitionBuilder setDependencyCheck(int dependencyCheck) { public BeanDefinitionBuilder setDependencyCheck(int dependencyCheck) {
beanDefinition.setDependencyCheck(dependencyCheck); this.beanDefinition.setDependencyCheck(dependencyCheck);
return this; return this;
} }
@ -316,7 +314,7 @@ public class BeanDefinitionBuilder {
*/ */
public BeanDefinitionBuilder applyCustomizers(BeanDefinitionCustomizer... customizers) { public BeanDefinitionBuilder applyCustomizers(BeanDefinitionCustomizer... customizers) {
for (BeanDefinitionCustomizer customizer : customizers) { for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(beanDefinition); customizer.customize(this.beanDefinition);
} }
return this; return this;
} }

5
spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java

@ -44,6 +44,7 @@ import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.InjectionPoint; import org.springframework.beans.factory.InjectionPoint;
import org.springframework.beans.factory.UnsatisfiedDependencyException; import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues; import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder; import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
import org.springframework.beans.factory.config.DependencyDescriptor; import org.springframework.beans.factory.config.DependencyDescriptor;
@ -140,7 +141,7 @@ class ConstructorResolver {
if (constructorToUse == null) { if (constructorToUse == null) {
// Need to resolve the constructor. // Need to resolve the constructor.
boolean autowiring = (chosenCtors != null || boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null; ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs; int minNrOfArgs;
@ -427,7 +428,7 @@ class ConstructorResolver {
AutowireUtils.sortFactoryMethods(candidates); AutowireUtils.sortFactoryMethods(candidates);
ConstructorArgumentValues resolvedValues = null; ConstructorArgumentValues resolvedValues = null;
boolean autowiring = (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
int minTypeDiffWeight = Integer.MAX_VALUE; int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Method> ambiguousFactoryMethods = null; Set<Method> ambiguousFactoryMethods = null;

2
spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java

@ -115,7 +115,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
this.destroyMethod = determineDestroyMethod(destroyMethodName); this.destroyMethod = determineDestroyMethod(destroyMethodName);
if (this.destroyMethod == null) { if (this.destroyMethod == null) {
if (beanDefinition.isEnforceDestroyMethod()) { if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Couldn't find a destroy method named '" + throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'"); destroyMethodName + "' on bean with name '" + beanName + "'");
} }
} }

10
spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java

@ -192,9 +192,6 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
@Nullable @Nullable
private Map<String, ?> schedulerContextMap; private Map<String, ?> schedulerContextMap;
@Nullable
private ApplicationContext applicationContext;
@Nullable @Nullable
private String applicationContextSchedulerContextKey; private String applicationContextSchedulerContextKey;
@ -213,6 +210,9 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
private boolean waitForJobsToCompleteOnShutdown = false; private boolean waitForJobsToCompleteOnShutdown = false;
@Nullable
private ApplicationContext applicationContext;
@Nullable @Nullable
private Scheduler scheduler; private Scheduler scheduler;
@ -564,10 +564,10 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
CollectionUtils.mergePropertiesIntoMap(this.quartzProperties, mergedProps); CollectionUtils.mergePropertiesIntoMap(this.quartzProperties, mergedProps);
if (this.dataSource != null) { if (this.dataSource != null) {
mergedProps.put(StdSchedulerFactory.PROP_JOB_STORE_CLASS, LocalDataSourceJobStore.class.getName()); mergedProps.setProperty(StdSchedulerFactory.PROP_JOB_STORE_CLASS, LocalDataSourceJobStore.class.getName());
} }
if (this.schedulerName != null) { if (this.schedulerName != null) {
mergedProps.put(StdSchedulerFactory.PROP_SCHED_INSTANCE_NAME, this.schedulerName); mergedProps.setProperty(StdSchedulerFactory.PROP_SCHED_INSTANCE_NAME, this.schedulerName);
} }
schedulerFactory.initialize(mergedProps); schedulerFactory.initialize(mergedProps);

11
spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -292,10 +292,7 @@ public class QuartzSupportTests {
bean.destroy(); bean.destroy();
} }
/** @Test // SPR-772
* Tests the creation of multiple schedulers (SPR-772)
*/
@Test
public void multipleSchedulers() throws Exception { public void multipleSchedulers() throws Exception {
ClassPathXmlApplicationContext ctx = context("multipleSchedulers.xml"); ClassPathXmlApplicationContext ctx = context("multipleSchedulers.xml");
try { try {
@ -363,8 +360,8 @@ public class QuartzSupportTests {
@SuppressWarnings("resource") @SuppressWarnings("resource")
public void schedulerAutoStartupFalse() throws Exception { public void schedulerAutoStartupFalse() throws Exception {
StaticApplicationContext context = new StaticApplicationContext(); StaticApplicationContext context = new StaticApplicationContext();
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition( BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SchedulerFactoryBean.class)
SchedulerFactoryBean.class).addPropertyValue("autoStartup", false).getBeanDefinition(); .addPropertyValue("autoStartup", false).getBeanDefinition();
context.registerBeanDefinition("scheduler", beanDefinition); context.registerBeanDefinition("scheduler", beanDefinition);
Scheduler bean = context.getBean("scheduler", Scheduler.class); Scheduler bean = context.getBean("scheduler", Scheduler.class);
assertFalse(bean.isStarted()); assertFalse(bean.isStarted());

8
spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java

@ -36,6 +36,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader; import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader;
import org.springframework.beans.factory.parsing.SourceExtractor; import org.springframework.beans.factory.parsing.SourceExtractor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinitionReader; import org.springframework.beans.factory.support.AbstractBeanDefinitionReader;
import org.springframework.beans.factory.support.BeanDefinitionReader; import org.springframework.beans.factory.support.BeanDefinitionReader;
import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistry;
@ -90,8 +91,8 @@ class ConfigurationClassBeanDefinitionReader {
/** /**
* Create a new {@link ConfigurationClassBeanDefinitionReader} instance that will be used * Create a new {@link ConfigurationClassBeanDefinitionReader} instance
* to populate the given {@link BeanDefinitionRegistry}. * that will be used to populate the given {@link BeanDefinitionRegistry}.
*/ */
ConfigurationClassBeanDefinitionReader(BeanDefinitionRegistry registry, SourceExtractor sourceExtractor, ConfigurationClassBeanDefinitionReader(BeanDefinitionRegistry registry, SourceExtractor sourceExtractor,
ResourceLoader resourceLoader, Environment environment, BeanNameGenerator importBeanNameGenerator, ResourceLoader resourceLoader, Environment environment, BeanNameGenerator importBeanNameGenerator,
@ -221,7 +222,7 @@ class ConfigurationClassBeanDefinitionReader {
beanDef.setFactoryBeanName(configClass.getBeanName()); beanDef.setFactoryBeanName(configClass.getBeanName());
beanDef.setUniqueFactoryMethodName(methodName); beanDef.setUniqueFactoryMethodName(methodName);
} }
beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE); beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata); AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
@ -264,7 +265,6 @@ class ConfigurationClassBeanDefinitionReader {
logger.debug(String.format("Registering bean definition for @Bean method %s.%s()", logger.debug(String.format("Registering bean definition for @Bean method %s.%s()",
configClass.getMetadata().getClassName(), beanName)); configClass.getMetadata().getClassName(), beanName));
} }
this.registry.registerBeanDefinition(beanName, beanDefToRegister); this.registry.registerBeanDefinition(beanName, beanDefToRegister);
} }

20
spring-context/src/main/java/org/springframework/context/support/GenericApplicationContext.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -361,8 +361,8 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
* bean definition metadata (typically declared as a lambda expression * bean definition metadata (typically declared as a lambda expression
* or method reference). * or method reference).
* @param beanClass the class of the bean * @param beanClass the class of the bean
* @param customizers one or more callbacks for customizing the * @param customizers one or more callbacks for customizing the factory's
* factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag * {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
* @since 5.0 * @since 5.0
* @see #registerBean(String, Class, Supplier, BeanDefinitionCustomizer...) * @see #registerBean(String, Class, Supplier, BeanDefinitionCustomizer...)
*/ */
@ -377,8 +377,8 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
* (again typically declared as a lambda expression or method reference). * (again typically declared as a lambda expression or method reference).
* @param beanName the name of the bean (may be {@code null}) * @param beanName the name of the bean (may be {@code null})
* @param beanClass the class of the bean * @param beanClass the class of the bean
* @param customizers one or more callbacks for customizing the * @param customizers one or more callbacks for customizing the factory's
* factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag * {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
* @since 5.0 * @since 5.0
* @see #registerBean(String, Class, Supplier, BeanDefinitionCustomizer...) * @see #registerBean(String, Class, Supplier, BeanDefinitionCustomizer...)
*/ */
@ -393,8 +393,8 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
* (again typically declared as a lambda expression or method reference). * (again typically declared as a lambda expression or method reference).
* @param beanClass the class of the bean * @param beanClass the class of the bean
* @param supplier a callback for creating an instance of the bean * @param supplier a callback for creating an instance of the bean
* @param customizers one or more callbacks for customizing the * @param customizers one or more callbacks for customizing the factory's
* factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag * {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
* @since 5.0 * @since 5.0
* @see #registerBean(String, Class, Supplier, BeanDefinitionCustomizer...) * @see #registerBean(String, Class, Supplier, BeanDefinitionCustomizer...)
*/ */
@ -410,10 +410,10 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
* <p>This method can be overridden to adapt the registration mechanism for * <p>This method can be overridden to adapt the registration mechanism for
* all {@code registerBean} methods (since they all delegate to this one). * all {@code registerBean} methods (since they all delegate to this one).
* @param beanName the name of the bean (may be {@code null}) * @param beanName the name of the bean (may be {@code null})
* @param beanClass the class of the bean (may be {@code null} if a name is given) * @param beanClass the class of the bean
* @param supplier a callback for creating an instance of the bean * @param supplier a callback for creating an instance of the bean
* @param customizers one or more callbacks for customizing the * @param customizers one or more callbacks for customizing the factory's
* factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag * {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
* @since 5.0 * @since 5.0
*/ */
public <T> void registerBean(@Nullable String beanName, Class<T> beanClass, @Nullable Supplier<T> supplier, public <T> void registerBean(@Nullable String beanName, Class<T> beanClass, @Nullable Supplier<T> supplier,

10
spring-context/src/main/java/org/springframework/scripting/config/ScriptBeanDefinitionParser.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -134,11 +134,11 @@ class ScriptBeanDefinitionParser extends AbstractBeanDefinitionParser {
String autowire = element.getAttribute(AUTOWIRE_ATTRIBUTE); String autowire = element.getAttribute(AUTOWIRE_ATTRIBUTE);
int autowireMode = parserContext.getDelegate().getAutowireMode(autowire); int autowireMode = parserContext.getDelegate().getAutowireMode(autowire);
// Only "byType" and "byName" supported, but maybe other default inherited... // Only "byType" and "byName" supported, but maybe other default inherited...
if (autowireMode == GenericBeanDefinition.AUTOWIRE_AUTODETECT) { if (autowireMode == AbstractBeanDefinition.AUTOWIRE_AUTODETECT) {
autowireMode = GenericBeanDefinition.AUTOWIRE_BY_TYPE; autowireMode = AbstractBeanDefinition.AUTOWIRE_BY_TYPE;
} }
else if (autowireMode == GenericBeanDefinition.AUTOWIRE_CONSTRUCTOR) { else if (autowireMode == AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR) {
autowireMode = GenericBeanDefinition.AUTOWIRE_NO; autowireMode = AbstractBeanDefinition.AUTOWIRE_NO;
} }
bd.setAutowireMode(autowireMode); bd.setAutowireMode(autowireMode);

154
spring-context/src/test/java/org/springframework/context/annotation/AnnotationConfigApplicationContextTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,7 +30,7 @@ import org.springframework.context.annotation6.ComponentForScanning;
import org.springframework.context.annotation6.ConfigForScanning; import org.springframework.context.annotation6.ConfigForScanning;
import org.springframework.context.annotation6.Jsr330NamedForScanning; import org.springframework.context.annotation6.Jsr330NamedForScanning;
import static java.lang.String.format; import static java.lang.String.*;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.springframework.util.StringUtils.*; import static org.springframework.util.StringUtils.*;
@ -41,12 +41,6 @@ import static org.springframework.util.StringUtils.*;
*/ */
public class AnnotationConfigApplicationContextTests { public class AnnotationConfigApplicationContextTests {
@Test(expected = IllegalArgumentException.class)
public void nullGetBeanParameterIsDisallowed() {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
context.getBean((Class<?>) null);
}
@Test @Test
public void scanAndRefresh() { public void scanAndRefresh() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@ -93,6 +87,39 @@ public class AnnotationConfigApplicationContextTests {
assertThat(testBean.name, equalTo("foo")); assertThat(testBean.name, equalTo("foo"));
} }
@Test
public void getBeanByTypeRaisesNoSuchBeanDefinitionException() {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
// attempt to retrieve a bean that does not exist
Class<?> targetType = Pattern.class;
try {
context.getBean(targetType);
fail("Should have thrown NoSuchBeanDefinitionException");
}
catch (NoSuchBeanDefinitionException ex) {
assertThat(ex.getMessage(), containsString(format("No qualifying bean of type '%s'", targetType.getName())));
}
}
@Test
public void getBeanByTypeAmbiguityRaisesException() {
ApplicationContext context = new AnnotationConfigApplicationContext(TwoTestBeanConfig.class);
try {
context.getBean(TestBean.class);
}
catch (NoSuchBeanDefinitionException ex) {
assertThat(ex.getMessage(),
allOf(
containsString("No qualifying bean of type '" + TestBean.class.getName() + "'"),
containsString("tb1"),
containsString("tb2")
)
);
}
}
/** /**
* Tests that Configuration classes are registered according to convention * Tests that Configuration classes are registered according to convention
* @see org.springframework.beans.factory.support.DefaultBeanNameGenerator#generateBeanName * @see org.springframework.beans.factory.support.DefaultBeanNameGenerator#generateBeanName
@ -119,6 +146,41 @@ public class AnnotationConfigApplicationContextTests {
assertNotNull(configObject); assertNotNull(configObject);
} }
@Test
public void autowiringIsEnabledByDefault() {
ApplicationContext context = new AnnotationConfigApplicationContext(AutowiredConfig.class);
assertThat(context.getBean(TestBean.class).name, equalTo("foo"));
}
@Test
public void nullReturningBeanPostProcessor() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(AutowiredConfig.class);
context.getBeanFactory().addBeanPostProcessor(new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return (bean instanceof TestBean ? null : bean);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
});
context.getBeanFactory().addBeanPostProcessor(new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
bean.getClass().getName();
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
bean.getClass().getName();
return bean;
}
});
context.refresh();
}
@Test @Test
public void individualBeans() { public void individualBeans() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@ -262,74 +324,6 @@ public class AnnotationConfigApplicationContextTests {
assertSame(context, context.getBean("b", BeanB.class).applicationContext); assertSame(context, context.getBean("b", BeanB.class).applicationContext);
} }
@Test
public void getBeanByTypeRaisesNoSuchBeanDefinitionException() {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
// attempt to retrieve a bean that does not exist
Class<?> targetType = Pattern.class;
try {
context.getBean(targetType);
fail("Should have thrown NoSuchBeanDefinitionException");
}
catch (NoSuchBeanDefinitionException ex) {
assertThat(ex.getMessage(), containsString(format("No qualifying bean of type '%s'", targetType.getName())));
}
}
@Test
public void getBeanByTypeAmbiguityRaisesException() {
ApplicationContext context = new AnnotationConfigApplicationContext(TwoTestBeanConfig.class);
try {
context.getBean(TestBean.class);
}
catch (NoSuchBeanDefinitionException ex) {
assertThat(ex.getMessage(),
allOf(
containsString("No qualifying bean of type '" + TestBean.class.getName() + "'"),
containsString("tb1"),
containsString("tb2")
)
);
}
}
@Test
public void autowiringIsEnabledByDefault() {
ApplicationContext context = new AnnotationConfigApplicationContext(AutowiredConfig.class);
assertThat(context.getBean(TestBean.class).name, equalTo("foo"));
}
@Test
public void nullReturningBeanPostProcessor() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(AutowiredConfig.class);
context.getBeanFactory().addBeanPostProcessor(new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return (bean instanceof TestBean ? null : bean);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
});
context.getBeanFactory().addBeanPostProcessor(new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
bean.getClass().getName();
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
bean.getClass().getName();
return bean;
}
});
context.refresh();
}
@Configuration @Configuration
static class Config { static class Config {
@ -351,14 +345,6 @@ public class AnnotationConfigApplicationContextTests {
} }
} }
static class ConfigMissingAnnotation {
@Bean
public TestBean testBean() {
return new TestBean();
}
}
@Configuration @Configuration
static class TwoTestBeanConfig { static class TwoTestBeanConfig {

3
spring-context/src/test/java/org/springframework/context/support/GenericApplicationContextTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,7 +19,6 @@ package org.springframework.context.support;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException; import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition;
import static org.junit.Assert.*; import static org.junit.Assert.*;

Loading…
Cancel
Save