Revisit GenericApplicationContext.registerBean constructor handling
Support for Kotlin primary constructor and non-default public constructors in addition to default instantiation, aligned with AnnotationConfigApplicationContext and model attribute processing. Issue: SPR-17292
This commit is contained in:
parent
50c9542796
commit
d3c08552e9
|
@ -1146,7 +1146,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
}
|
||||
}
|
||||
|
||||
// Need to determine the constructor...
|
||||
// Candidate constructors for autowiring?
|
||||
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
|
||||
if (ctors != null ||
|
||||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
|
||||
|
@ -1154,6 +1154,12 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
return autowireConstructor(beanName, mbd, ctors, args);
|
||||
}
|
||||
|
||||
// Preferred constructors for default construction?
|
||||
ctors = mbd.getPreferredConstructors();
|
||||
if (ctors != null) {
|
||||
return autowireConstructor(beanName, mbd, ctors, null);
|
||||
}
|
||||
|
||||
// No special handling: simply use no-arg constructor.
|
||||
return instantiateBean(beanName, mbd);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -335,6 +336,18 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
|||
return (targetType != null ? targetType : ResolvableType.forClass(getBeanClass()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine preferred constructors to use for default construction, if any.
|
||||
* Constructor arguments will be autowired if necessary.
|
||||
* @return one or more preferred constructors, or {@code null} if none
|
||||
* (in which case the regular no-arg default constructor will be called)
|
||||
* @since 5.1
|
||||
*/
|
||||
@Nullable
|
||||
public Constructor<?>[] getPreferredConstructors() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a factory method name that refers to a non-overloaded method.
|
||||
*/
|
||||
|
|
|
@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -17,9 +17,11 @@
|
|||
package org.springframework.context.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
|
@ -27,9 +29,9 @@ import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
|||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionCustomizer;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
|
@ -360,9 +362,10 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
|
|||
* Register a bean from the given bean class, optionally customizing its
|
||||
* bean definition metadata (typically declared as a lambda expression
|
||||
* or method reference).
|
||||
* @param beanClass the class of the bean
|
||||
* @param customizers one or more callbacks for customizing the
|
||||
* factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
|
||||
* @param beanClass the class of the bean (resolving a public constructor
|
||||
* to be autowired, possibly simply the default constructor)
|
||||
* @param customizers one or more callbacks for customizing the factory's
|
||||
* {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
|
||||
* @since 5.0
|
||||
* @see #registerBean(String, Class, Supplier, BeanDefinitionCustomizer...)
|
||||
*/
|
||||
|
@ -376,13 +379,16 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
|
|||
* method reference), optionally customizing its bean definition metadata
|
||||
* (again typically declared as a lambda expression or method reference).
|
||||
* @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 (resolving a public constructor
|
||||
* to be autowired, possibly simply the default constructor)
|
||||
* @param customizers one or more callbacks for customizing the
|
||||
* factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
|
||||
* @since 5.0
|
||||
* @see #registerBean(String, Class, Supplier, BeanDefinitionCustomizer...)
|
||||
*/
|
||||
public final <T> void registerBean(@Nullable String beanName, Class<T> beanClass, BeanDefinitionCustomizer... customizers) {
|
||||
public final <T> void registerBean(
|
||||
@Nullable String beanName, Class<T> beanClass, BeanDefinitionCustomizer... customizers) {
|
||||
|
||||
registerBean(beanName, beanClass, null, customizers);
|
||||
}
|
||||
|
||||
|
@ -393,12 +399,14 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
|
|||
* (again typically declared as a lambda expression or method reference).
|
||||
* @param beanClass the class of the bean
|
||||
* @param supplier a callback for creating an instance of the bean
|
||||
* @param customizers one or more callbacks for customizing the
|
||||
* factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
|
||||
* @param customizers one or more callbacks for customizing the factory's
|
||||
* {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
|
||||
* @since 5.0
|
||||
* @see #registerBean(String, Class, Supplier, BeanDefinitionCustomizer...)
|
||||
*/
|
||||
public final <T> void registerBean(Class<T> beanClass, Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {
|
||||
public final <T> void registerBean(
|
||||
Class<T> beanClass, Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {
|
||||
|
||||
registerBean(null, beanClass, supplier, customizers);
|
||||
}
|
||||
|
||||
|
@ -410,22 +418,63 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
|
|||
* <p>This method can be overridden to adapt the registration mechanism for
|
||||
* all {@code registerBean} methods (since they all delegate to this one).
|
||||
* @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 supplier a callback for creating an instance of the bean
|
||||
* @param customizers one or more callbacks for customizing the
|
||||
* factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
|
||||
* @param beanClass the class of the bean
|
||||
* @param supplier a callback for creating an instance of the bean (in case
|
||||
* of {@code null}, resolving a public constructor to be autowired instead)
|
||||
* @param customizers one or more callbacks for customizing the factory's
|
||||
* {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
|
||||
* @since 5.0
|
||||
*/
|
||||
public <T> void registerBean(@Nullable String beanName, Class<T> beanClass, @Nullable Supplier<T> supplier,
|
||||
BeanDefinitionCustomizer... customizers) {
|
||||
public <T> void registerBean(@Nullable String beanName, Class<T> beanClass,
|
||||
@Nullable Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {
|
||||
|
||||
BeanDefinitionBuilder builder = (supplier != null ?
|
||||
BeanDefinitionBuilder.genericBeanDefinition(beanClass, supplier) :
|
||||
BeanDefinitionBuilder.genericBeanDefinition(beanClass));
|
||||
BeanDefinition beanDefinition = builder.applyCustomizers(customizers).getRawBeanDefinition();
|
||||
ClassDerivedBeanDefinition beanDefinition = new ClassDerivedBeanDefinition(beanClass);
|
||||
if (supplier != null) {
|
||||
beanDefinition.setInstanceSupplier(supplier);
|
||||
}
|
||||
for (BeanDefinitionCustomizer customizer : customizers) {
|
||||
customizer.customize(beanDefinition);
|
||||
}
|
||||
|
||||
String nameToUse = (beanName != null ? beanName : beanClass.getName());
|
||||
registerBeanDefinition(nameToUse, beanDefinition);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@link RootBeanDefinition} marker subclass for {@code #registerBean} based
|
||||
* registrations with flexible autowiring for public constructors.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
private static class ClassDerivedBeanDefinition extends RootBeanDefinition {
|
||||
|
||||
public ClassDerivedBeanDefinition(Class<?> beanClass) {
|
||||
super(beanClass);
|
||||
}
|
||||
|
||||
public ClassDerivedBeanDefinition(ClassDerivedBeanDefinition original) {
|
||||
super(original);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Constructor<?>[] getPreferredConstructors() {
|
||||
Class<?> clazz = getBeanClass();
|
||||
Constructor<?> primaryCtor = BeanUtils.findPrimaryConstructor(clazz);
|
||||
if (primaryCtor != null) {
|
||||
return new Constructor<?>[] {primaryCtor};
|
||||
}
|
||||
Constructor<?>[] publicCtors = clazz.getConstructors();
|
||||
if (publicCtors.length > 0) {
|
||||
return publicCtors;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RootBeanDefinition cloneBeanDefinition() {
|
||||
return new ClassDerivedBeanDefinition(this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -90,6 +90,21 @@ public class AnnotationConfigApplicationContextTests {
|
|||
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())));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that Configuration classes are registered according to convention
|
||||
* @see org.springframework.beans.factory.support.DefaultBeanNameGenerator#generateBeanName
|
||||
|
@ -116,6 +131,41 @@ public class AnnotationConfigApplicationContextTests {
|
|||
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
|
||||
public void individualBeans() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
|
@ -299,74 +349,6 @@ public class AnnotationConfigApplicationContextTests {
|
|||
assertEquals(FactoryBean.class, context.getType("&fb"));
|
||||
}
|
||||
|
||||
@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
|
||||
static class Config {
|
||||
|
|
|
@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -19,8 +19,10 @@ package org.springframework.context.support;
|
|||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
@ -104,4 +106,140 @@ public class GenericApplicationContextTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void individualBeans() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBean(BeanA.class);
|
||||
context.registerBean(BeanB.class);
|
||||
context.registerBean(BeanC.class);
|
||||
context.refresh();
|
||||
|
||||
assertSame(context.getBean(BeanB.class), context.getBean(BeanA.class).b);
|
||||
assertSame(context.getBean(BeanC.class), context.getBean(BeanA.class).c);
|
||||
assertSame(context, context.getBean(BeanB.class).applicationContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void individualNamedBeans() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBean("a", BeanA.class);
|
||||
context.registerBean("b", BeanB.class);
|
||||
context.registerBean("c", BeanC.class);
|
||||
context.refresh();
|
||||
|
||||
assertSame(context.getBean("b"), context.getBean("a", BeanA.class).b);
|
||||
assertSame(context.getBean("c"), context.getBean("a", BeanA.class).c);
|
||||
assertSame(context, context.getBean("b", BeanB.class).applicationContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void individualBeanWithSupplier() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBean(BeanA.class,
|
||||
() -> new BeanA(context.getBean(BeanB.class), context.getBean(BeanC.class)));
|
||||
context.registerBean(BeanB.class, BeanB::new);
|
||||
context.registerBean(BeanC.class, BeanC::new);
|
||||
context.refresh();
|
||||
|
||||
assertTrue(context.getBeanFactory().containsSingleton(BeanA.class.getName()));
|
||||
assertSame(context.getBean(BeanB.class), context.getBean(BeanA.class).b);
|
||||
assertSame(context.getBean(BeanC.class), context.getBean(BeanA.class).c);
|
||||
assertSame(context, context.getBean(BeanB.class).applicationContext);
|
||||
|
||||
assertArrayEquals(new String[] {BeanA.class.getName()},
|
||||
context.getDefaultListableBeanFactory().getDependentBeans(BeanB.class.getName()));
|
||||
assertArrayEquals(new String[] {BeanA.class.getName()},
|
||||
context.getDefaultListableBeanFactory().getDependentBeans(BeanC.class.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void individualBeanWithSupplierAndCustomizer() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBean(BeanA.class,
|
||||
() -> new BeanA(context.getBean(BeanB.class), context.getBean(BeanC.class)),
|
||||
bd -> bd.setLazyInit(true));
|
||||
context.registerBean(BeanB.class, BeanB::new);
|
||||
context.registerBean(BeanC.class, BeanC::new);
|
||||
context.refresh();
|
||||
|
||||
assertFalse(context.getBeanFactory().containsSingleton(BeanA.class.getName()));
|
||||
assertSame(context.getBean(BeanB.class), context.getBean(BeanA.class).b);
|
||||
assertSame(context.getBean(BeanC.class), context.getBean(BeanA.class).c);
|
||||
assertSame(context, context.getBean(BeanB.class).applicationContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void individualNamedBeanWithSupplier() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBean("a", BeanA.class,
|
||||
() -> new BeanA(context.getBean(BeanB.class), context.getBean(BeanC.class)));
|
||||
context.registerBean("b", BeanB.class, BeanB::new);
|
||||
context.registerBean("c", BeanC.class, BeanC::new);
|
||||
context.refresh();
|
||||
|
||||
assertTrue(context.getBeanFactory().containsSingleton("a"));
|
||||
assertSame(context.getBean("b", BeanB.class), context.getBean(BeanA.class).b);
|
||||
assertSame(context.getBean("c"), context.getBean("a", BeanA.class).c);
|
||||
assertSame(context, context.getBean("b", BeanB.class).applicationContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void individualNamedBeanWithSupplierAndCustomizer() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBean("a", BeanA.class,
|
||||
() -> new BeanA(context.getBean(BeanB.class), context.getBean(BeanC.class)),
|
||||
bd -> bd.setLazyInit(true));
|
||||
context.registerBean("b", BeanB.class, BeanB::new);
|
||||
context.registerBean("c", BeanC.class, BeanC::new);
|
||||
context.refresh();
|
||||
|
||||
assertFalse(context.getBeanFactory().containsSingleton("a"));
|
||||
assertSame(context.getBean("b", BeanB.class), context.getBean(BeanA.class).b);
|
||||
assertSame(context.getBean("c"), context.getBean("a", BeanA.class).c);
|
||||
assertSame(context, context.getBean("b", BeanB.class).applicationContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void individualBeanWithNullReturningSupplier() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBean("a", BeanA.class, () -> null);
|
||||
context.registerBean("b", BeanB.class, BeanB::new);
|
||||
context.registerBean("c", BeanC.class, BeanC::new);
|
||||
context.refresh();
|
||||
|
||||
assertTrue(ObjectUtils.containsElement(context.getBeanNamesForType(BeanA.class), "a"));
|
||||
assertTrue(ObjectUtils.containsElement(context.getBeanNamesForType(BeanB.class), "b"));
|
||||
assertTrue(ObjectUtils.containsElement(context.getBeanNamesForType(BeanC.class), "c"));
|
||||
assertTrue(context.getBeansOfType(BeanA.class).isEmpty());
|
||||
assertSame(context.getBean(BeanB.class), context.getBeansOfType(BeanB.class).values().iterator().next());
|
||||
assertSame(context.getBean(BeanC.class), context.getBeansOfType(BeanC.class).values().iterator().next());
|
||||
}
|
||||
|
||||
|
||||
static class BeanA {
|
||||
|
||||
BeanB b;
|
||||
BeanC c;
|
||||
|
||||
public BeanA(BeanB b, BeanC c) {
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
}
|
||||
}
|
||||
|
||||
static class BeanB implements ApplicationContextAware {
|
||||
|
||||
ApplicationContext applicationContext;
|
||||
|
||||
public BeanB() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
}
|
||||
|
||||
static class BeanC {}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue