一次更新 Error creating bean with name 'eurekaAutoServiceRegistration'

一次服务更新进行升级时

October 18th 2018, 18:05:35.767	[545]: ++ exit 143
October 18th 2018, 18:05:35.610	[545]: 2018-10-18 18:05:35.611  INFO 13 --- [      Thread-10] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
October 18th 2018, 18:05:35.608	[545]: 
October 18th 2018, 18:05:35.608	[545]: 	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1009)
October 18th 2018, 18:05:35.608	[545]: 	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523)
October 18th 2018, 18:05:35.608	[545]: 	at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1033)
October 18th 2018, 18:05:35.608	[545]: 	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:961)
October 18th 2018, 18:05:35.608	[545]: 	at org.springframework.context.support.AbstractApplicationContext$2.run(AbstractApplicationContext.java:928)
October 18th 2018, 18:05:35.608	[545]: 	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:968)
October 18th 2018, 18:05:35.607	[545]: 	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:389)
October 18th 2018, 18:05:35.607	[545]: 	at org.springframework.cloud.context.named.NamedContextFactory.destroy(NamedContextFactory.java:76)
October 18th 2018, 18:05:35.607	[545]: 	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:994)
October 18th 2018, 18:05:35.607	[545]: 	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578)
October 18th 2018, 18:05:35.607	[545]: 	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554)
October 18th 2018, 18:05:35.607	[545]: 	at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:961)
October 18th 2018, 18:05:35.607	[545]: 	at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:272)
October 18th 2018, 18:05:35.607	[545]: 	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:337)
October 18th 2018, 18:05:35.606	[545]: 	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:383)
October 18th 2018, 18:05:35.606	[545]: 	at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:250)
October 18th 2018, 18:05:35.606	[545]: 	at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:137)
October 18th 2018, 18:05:35.606	[545]: 	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
October 18th 2018, 18:05:35.606	[545]: 	at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:174)
October 18th 2018, 18:05:35.606	[545]: 	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167)
October 18th 2018, 18:05:35.606	[545]: 	at org.springframework.context.event.ApplicationListenerMethodAdapter.getTargetBean(ApplicationListenerMethodAdapter.java:280)
October 18th 2018, 18:05:35.605	[545]: 
October 18th 2018, 18:05:35.605	[545]: 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!)
October 18th 2018, 18:05:35.605	[545]: 	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
October 18th 2018, 18:05:35.605	[545]: 	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081)
October 18th 2018, 18:05:35.605	[545]: 2018-10-18 18:05:35.604  WARN 13 --- [      Thread-10] s.c.a.AnnotationConfigApplicationContext : Exception thrown from ApplicationListener handling ContextClosedEvent
October 18th 2018, 18:05:35.605	[545]: 	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
October 18th 2018, 18:05:35.605	[545]: 	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:216)
October 18th 2018, 18:05:35.601	[545]: 	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1009)
October 18th 2018, 18:05:35.601	[545]: 	at org.springframework.context.support.AbstractApplicationContext$2.run(AbstractApplicationContext.java:928)
October 18th 2018, 18:05:35.601	[545]: 
October 18th 2018, 18:05:35.601	[545]: 2018-10-18 18:05:35.603  INFO 13 --- [      Thread-10] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@145bce9d: startup date [Thu Oct 18 12:35:30 GMT+08:00 2018]; parent: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@50e8e914
October 18th 2018, 18:05:35.601	[545]: 	at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1033)
October 18th 2018, 18:05:35.600	[545]: 	at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:272)
October 18th 2018, 18:05:35.600	[545]: 	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:961)
October 18th 2018, 18:05:35.600	[545]: 	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:968)
October 18th 2018, 18:05:35.600	[545]: 	at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:961)
October 18th 2018, 18:05:35.600	[545]: 	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578)
October 18th 2018, 18:05:35.600	[545]: 	at org.springframework.cloud.context.named.NamedContextFactory.destroy(NamedContextFactory.java:76)
October 18th 2018, 18:05:35.600	[545]: 	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554)
October 18th 2018, 18:05:35.600	[545]: 	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523)
October 18th 2018, 18:05:35.599	[545]: 	at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:137)
October 18th 2018, 18:05:35.599	[545]: 	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
October 18th 2018, 18:05:35.599	[545]: 	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167)
October 18th 2018, 18:05:35.599	[545]: 	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:337)
October 18th 2018, 18:05:35.599	[545]: 	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:994)
October 18th 2018, 18:05:35.599	[545]: 	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:383)
October 18th 2018, 18:05:35.599	[545]: 	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:389)
October 18th 2018, 18:05:35.598	[545]: 	at org.springframework.context.event.ApplicationListenerMethodAdapter.getTargetBean(ApplicationListenerMethodAdapter.java:280)
October 18th 2018, 18:05:35.598	[545]: 	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
October 18th 2018, 18:05:35.598	[545]: 	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
October 18th 2018, 18:05:35.598	[545]: 	at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:250)
October 18th 2018, 18:05:35.598	[545]: 	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081)
October 18th 2018, 18:05:35.598	[545]: 	at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:174)
October 18th 2018, 18:05:35.597	[545]: 2018-10-18 18:05:35.598  WARN 13 --- [      Thread-10] s.c.a.AnnotationConfigApplicationContext : Exception thrown from ApplicationListener handling ContextClosedEvent
October 18th 2018, 18:05:35.597	[545]: 	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:216)
October 18th 2018, 18:05:35.597	[545]: 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!)
October 18th 2018, 18:05:35.597	[545]: 
October 18th 2018, 18:05:35.596	[545]: 2018-10-18 18:05:35.597  INFO 13 --- [      Thread-10] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1ec4d67e: startup date [Thu Oct 18 15:17:15 GMT+08:00 2018]; parent: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@50e8e914

The root cause is when closing ApplicationContext, it will destroy all singleton bean, eurekaAutoServiceRegistration is destroyed first, then feignContext. When destroy feignContext, it will close the ApplicationContext associated with each FeignClient. Since eurekaAutoServiceRegistration listen on ContextClosedEvent, those events will be sent to that bean. Unfortunately because it has been destroyed, so we got the above exception (try to create bean in destruction).

@EventListener(ContextClosedEvent.class)
public void onApplicationEvent(ContextClosedEvent event) {
	// register in case meta data changed
	stop();
}

根本原因是:当关闭ApplicationContext,会关闭所有的单例:先是eurekaAutoServiceRegistration,然后是feignContext。当关闭feignContext时,会关闭与每个FeignClient关联的ApplicationContext,因为eurekaAutoServiceRegistration监听ContextClosedEvent,ContextClosedEvent的所有事件将会被发送到那个bean上,因为它已经被关闭了,所以会出现上面异常。

Found a workaround. Also added more details about the root cause.

When ApplicationContext shutdown, it will destroy all disposable beans (and beans depend on them). In this case:

FeignContext implements DisposableBean interface
InetUtils implements AutoCloseable interface
EurekaServiceRegistry has a public close method
So they are all considered as disposable beans. Since EurekaAutoServiceRegistration depends on InetUtils and EurekaServiceRegistry beans, so if either bean is destroyed, EurekaAutoServiceRegistration will be destroyed.
Destroy follow First In, Last Out order. Usually application code will not depends on InetUtils or EurekaServiceRegistry, but they depends on FeignClient interfaces. That means FeignContext usually get instituted before InetUtils and EurekaServiceRegistry, so it will be destroyed after them:

InetUtils or EurekaServiceRegistry to be destroyed.
Destroy EurekaAutoServiceRegistration first.
Destroy InetUtils and EurekaServiceRegistry.
Destroy FeignContext which will shutdown all ApplicationContext associated with FeignClients.
EurekaAutoServiceRegistration listen on ContextClosedEvent but it has been destroyed. ApplicationContext will try to create it again, got exception.
Workaround

Make sure InetUtils and EurekaServiceRegistry are instituted before FeignContext. So the sequence become:

Destroy FeignContext which will shutdown all ApplicationContext associated with FeignClients.
EurekaAutoServiceRegistration listen on ContextClosedEvent and processed those events.
InetUtils or EurekaServiceRegistry to be destroyed.
Destroy EurekaAutoServiceRegistration first.
Destroy InetUtils and EurekaServiceRegistry.
There are several ways to do that. The recommended solution is implement a BeanFactoryPostProcessor:

一个 解决方案:

@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));
    }
}

这个问题还有更好的解决方案 上述的解决方案 貌似只是让异常不再抛出来
有其他解决方案 可以留言评论
QQ: 986359351

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值