1、问题描述
Spring Boot工程在启动的过程中没有提示下述错误信息,但是在mvn install的时候提示
Error creating bean with name 'apacheHttpClientFactory’
2018-12-05 14:55:20.967 WARN [-,,,] 36552 --- [ender@4a89722e}]
s.c.a.AnnotationConfigApplicationContext : Exception encountered during
context initialization - cancelling refresh attempt: org.springframework
.beans.factory.UnsatisfiedDependencyException: Error creating bean with
name 'httpClient' defined in org.springframework.cloud.netflix.ribbon.
apache.HttpClientRibbonConfiguration$ApacheHttpClientConfiguration:
Unsatisfied dependency expressed through method 'httpClient' parameter 0;
nested exception is org.springframework.beans.factory
.BeanCreationNotAllowedException: Error creating bean with
name 'apacheHttpClientFactory': Singleton bean creation not allowed
while singletons of this factory are in destruction
(Do not request a bean from a BeanFactory in a destroy method implementation!)
Error creating bean with name 'eurekaAutoServiceRegistration’
2018-12-05 14:55:22.201 WARN [-,,,] 36552 --- [ Thread-7] s.c.a.AnnotationConfigApplicationContext : Exception thrown
from ApplicationListener handling ContextClosedEvent
org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'eurekaAutoServiceRegistration':
Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory
in a destroy method implementation!)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:208)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1087)
at org.springframework.context.event.ApplicationListenerMethodAdapter.getTargetBean(ApplicationListenerMethodAdapter.java:288)
at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:258)
at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:180)
at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:142)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:400)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:406)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:354)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:998)
at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:965)
at org.springframework.cloud.context.named.NamedContextFactory.destroy(NamedContextFactory.java:76)
at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:256)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:571)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:543)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:954)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:504)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:961)
at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1039)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1015)
at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:935)
2、问题分析
可能和Spring管理Bean的生命周期有关,具体没有研究,参考网上的资料简单看了看。
3、问题解决
参考https://github.com/dengly/spring-cloud-study/issues/5解决办法,添加了一个FeignBeanFactoryPostProcessor。
/**
* @Auther: chisj chisj@foxmal.com
* @Date: 2018-12-05 10:48
* @Description:
*/
@Component
public class FeignBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (containsBeanDefinition(beanFactory, "feignContext", "eurekaAutoServiceRegistration")) {
BeanDefinition bd = beanFactory.getBeanDefinition("feignContext");
bd.setDependsOn("eurekaAutoServiceRegistration");
}
}
private boolean containsBeanDefinition(ConfigurableListableBeanFactory beanFactory, String... beans) {
return Arrays.stream(beans).allMatch(b -> beanFactory.containsBeanDefinition(b));
}
}
这样只能解决Error creating bean with name 'eurekaAutoServiceRegistration的问题。
在IDEA里面有一个Endpoints–》Beans的功能,找到了feignContext----》eurekaAutoServiceRegistration
顺着这个思路,找到了apacheHttpClientFactory----》traceHttpClientBuilder
于是,再添加一个关于apacheHttpClientFactory的类HttpClientBeanFactoryPostProcessor
/**
* @Auther: chisj chisj@foxmal.com
* @Date: 2018-12-05 14:19
* @Description:
*/
@Component
public class HttpClientBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (containsBeanDefinition(beanFactory, "apacheHttpClientFactory", "traceHttpClientBuilder")) {
BeanDefinition bd = beanFactory.getBeanDefinition("apacheHttpClientFactory");
bd.setDependsOn("traceHttpClientBuilder");
}
}
private boolean containsBeanDefinition(ConfigurableListableBeanFactory beanFactory, String... beans) {
return Arrays.stream(beans).allMatch(b -> beanFactory.containsBeanDefinition(b));
}
}
再次打包,没有上述的错误信息了。
4、参考资料
1 【Spring源码–IOC容器的实现】(三)BeanDefinition的载入和解析【I】
2 Spring源码分析——BeanFactory体系之接口详细分析
3 spring源码深度解析(笔记四)–bean的加载
4 org.springframework.beans.factory.BeanCreationNotAllowedException #5
5 BeanCreationNotAllowedException on shutdown for EurekaDiscoveryClientConfiguration