开发者

How to implement a resilient bean in Spring?

开发者 https://www.devze.com 2023-03-18 12:36 出处:网络
I have a Spring bean that access an external system through http in its constructor. If the external system is not available at startup the bean cannot be created and application fails to start proper

I have a Spring bean that access an external system through http in its constructor. If the external system is not available at startup the bean cannot be created and application fails to start properly.

I want my application to be able to start regardless of extenal systems. I would rather have missing functionality for a while than having to restart the application.

I know this should be achievable in Spring with the right choice of scope and a proxying bean factory but I'm not sure how actually do it. It seems to me that most parts of Spring AOP is aimed at modifying targets that are succesfully created and is not able to handle excpetions during creation or am I wrong?

In short: I want a proxy that create开发者_JAVA技巧s the target bean at first access and then retains that instance as long as it works. If it fails to create it, it should throw an exception and retry next time the proxy is called.

So, how would you implement this functionality?


Have you tried lazy bean initiation?

<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/>

you should not set this bean as property to Singleton bean because it will initiate it on startup.


I ended up creating a ResilientBeanProxy that defer the actual creation to later, so yes, it is almost as Spring's lazy init but with the added feature that it handles exceptions during init. e.g. it will not halt the creation of the application context an error occurs during startup.

If the creation fails, it will be retried at the next invocation.


Consider if Your bean really depends on remote resource in construction time? Maybe You could simply use lazy init here? You wouldn't call this external system in constructor, but on first call to it's method when the remote resource is needed. Than if the resource is not there, thow a kind of ResourceUnavailableException with a message 'Try again later'.


An old thread, but I was just trying to follow a similar pattern and in my scenario Lazy init worked.

As long as both the bean and injection point (@Autowire or constructor parameter) are marked as @Lazy then the bean wont be created until first accessed.

If the bean creation fails (throws an Exception), the Component accessing the bean can handle the exception. However, as no instance of the bean is added to the context (because creation failed), the next access of the bean will try to create it again.

This seems to work fine in my context, where the bean is a connection to a remote webservice, the WSDL of which might not be available at startup.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号