简体   繁体   中英

Why can't Spring autowire a bean called environment?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM