The code below creates a parent context and puts a class called Environment
into the context with a name environment
which is generated through a AnnotationBeanNameGenerator
. This then gets autowired into TestChild
which is in a child context.
However, with the AnnotationBeanNameGenerator
generating the name of environment
for the Environment
class, when I start the child context (the web server) I get an error saying that it can't autowire the bean. If I change the name of the bean to something fixed (ie some guid) it works fine.
I've used component-scan in the code below, but these are the only classes in my project.
@RestController
public class TestChild {
@Autowired
public TestChild(Environment environment) { }
}
--
public class Environment {
public Environment() {
System.err.print("hey");
}
}
--
AnnotationConfigApplicationContext parentContext = new AnnotationConfigApplicationContext();
parentContext.addBeanFactoryPostProcessor(new BeanDefinitionRegistryPostProcessor() {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
BeanDefinition bd = new RootBeanDefinition(Environment.class, null, null);
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
registry.registerBeanDefinition(generator.generateBeanName(bd, registry), bd);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { }
});
parentContext.refresh();
AnnotationConfigWebApplicationContext childContext = new AnnotationConfigWebApplicationContext();
childContext.setParent(parentContext);
childContext.scan("child");
ServletContextHandler contextHandler = new ServletContextHandler();
contextHandler.addServlet(new ServletHolder(new DispatcherServlet(childContext)), "/*");
contextHandler.addEventListener(new ContextLoaderListener(childContext));
Server server = new Server(8080) {{ setHandler(contextHandler); }};
server.start();
server.join();
You are probably encountering this problem because the application context already contains a bean named environment
as part of the core Spring functionality.
You can see this below:
org.springframework.core.env.Environment e = applicationContext.getBean("environment");
LOGGER.info(e.getClass().getName());
//prints: org.springframework.web.context.support.StandardServletEnvironment
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.