How to implement a resilient bean in Spring? - java

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 creates 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.

Related

How create custome spring scope which provide beans similar to session scope?

It is needed to define Spring scope which will provide a proxy to the beans and reload/recreate target beans when say an event occurs. The behavior is similar to session beans, except there is no http session.
Does Spring provide a way for such bean proxing and scope manipulation?
UPDATED
Say that it is need to change externalUrl which is used to send http requests. So the application has to switch to new bean with new http connection pool created.
When bean autowired directly it is imposible to recreate it, especially when it is used in many places. So I search some way to inject a proxy instead of it and recreate target instace without altering caller code.
It is possible. I can't tell you exactly how to do it, but if you're able to, something like Spring Cloud Config would be exactly what you want. If you can't adopt that, I would start digging into the source code. The class you'd want to start with is the RefreshScope - from there, you should be able to figure out how it works and how it re-creates beans. I'm sorry that I can't provide more direction.

Update spring beans dynamically. Is it possible?

Is there a way to update a Spring bean dynamically if the spring beans configuration changes?
E.g. assume that I have a spring bean with boolean property x and the spring beans has the value true when the application starts.
So spring creates the bean with the property x set to true.
Is there a way so that if I changes the property to x (while the application is running) that the property will be updated e.g. to false?
Calling the setter for x setX() method will do that.
But it should not be a prototype bean.
it is possible with the jrebel-spring integration. it monitors your configuration and TRIES to re-wire your beans at runtime.
Though i would not use it in production...only for playing around, testing etc
Spring reads configuration files at startup. If you really need to update configs while application running, you should manually implement all the chain: detecting config changes, validating config, detecting changed beans, updating beans in context.
Spring beans can be initialized using applicationContext.xml or even programatically. In your case; you will need to remove configurations from xml and add into java program. You can get some idea from How to programmatically create bean definition with injected properties? . Other good links were also available on google.

What happens when spring bean definition file loaded into application multiple times?

I am just curious to know when a Spring.xml file loaded into application multiple times into an application using ClassPathXmlApplicationContext. For example if I want to get the services defined in Spring.xml into my claases by creating new instance of ApplicationContext in each class . Does this approach create each time new beans without destroying the previously created beans?Does this creates any memory problems ? When I see in ClassPathXmlApplicationContext API in spring website I found this.Does this refresh creates new bean definition of existing bean by destroying existed one?
ClassPathXmlApplicationContext(String... configLocations)
***Create a new ClassPathXmlApplicationContext, loading the definitions from the given XML files and automatically refreshing the context.***
When the same xml file is loaded several times spring creates the same beans several times. In most cases this does not cause problems except initiation time. But sometimes you can get conflicts. For example if you have bean that is listening to TCP port and then open yet another bean that tries to connect to the same port it fails.

Is it possible in Springframework 2.5.6 to have scope="session" create the object on session create

I've got a project using Jetspeed portal and Springframework 2.5.6 where I need a Jetspeed level service to be unique for each user logged in. This would be best done using Spring AOP and scope="session". The problem is, that these are behind the scenes beans that need to be running as soon as the session in initiated. It appears that Spring's AOP chooses a lazy load design and does not create or init the actual implementation until a method on the bean is called.
Is there a way to force Spring AOP to create the new bean as soon as the session object is created?
An excellent question. The easiest option that springs to mind (if you'll pardon the expression) is to wire your session-scoped bean into the controller that is invoked when the first request of the session comes in (and to do this, the controller would have to either be a session-scoped bean itself, or your bean would need to use aop:scoped-proxy).
If different controllers could be invoked at the start of the session, then you could wire the bean into a session-scoped interceptor instead, and configure your url mapping to pass the requests through the interceptor, ensuring that the bean is initialized right at the start of the session.
I can't really think of a more elegant way to do this. You could potentially create a custom HttpSessionListener which calls getBean("my-session-scoped-bean") on the app context when sessionCreated() is called, but that's a bit clunky.

Different bean configuration depending on runtime?

I have a bean, say manager, which is used all over my application for remoting. The bean is using httpclient which in turn can be configured with or without proxy. But this configuration can be only one. What i want in my application is: when the application started, the user is asked does she want to use a proxy or not? And depending on the user's answer the bean is properly configured and only then started. Some sort of dynamic configuration during runtime.
Is it possible or maybe I should achieve this some other way?
Thank you.
Why can't you call setProxy() on httpclient configuration depending on user's input?
Alternatively you can configure httpclient as bean in Spring context (either directly or create a simple wrapper) two times - one with proxy and one without. Then manager can choose which one to use depending on user's input (both can be injected into manager).

Categories

Resources