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

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.

Related

How to create a bean in spring that is available to all users in my app?

I'm building an online chat application in spring just like the one on Facebook. I want to create a bean with a property[Array] called active-users. Then performs the following:
Whenever a user logs in, I'll add his/her userId into the array.
When an other user logs in, I'll display the users that are
currently online.
How do I create a bean which is available at all times?
For Ex : In servlets, this can be achieved by using the Servlet context :
ServletContext context = request.getServletContext();
context.setAttribute("userId", "123");
All beans in Spring are singletons by default, they will be alive during the whole application's lifecycle unless you'll do something with the spring context.
So just create a spring bean and declare a global list in it. You can access it anywhere where the spring bean will be injected from the current context.
It's simpler with Spring than in a pure servlet application, because all beans declared in root application context reside in fact automatically in the ServletContext and as such are unique in the application. And Spring can natively inject them in any controller or service bean to allow you to use them at will.
The only limit, is that they are unique per instance, so it won't be enough it you had a farm of servers for your application.

EJB properties file

In my project I have 2 modules, a ejb and a war module. In the war module i have a properties file that is processed when I start the web application (by a listener). For each property in this properties file, i add it to the servlet context.
So, my question is: is it possible to access this properties, in the servlet context, from a enterprise java bean in the ejb module? I want to do something like this, but in a ejb:
ServletContext sc = myservlet.getServletContext();
String xpto = sc.getAttribute("my-attr");
If this is not possible, what is the alternative?
Thanks!
P.S I'm using netbeans and glassfish.
ServletContext is always loaded ahead in the Servlet lifecycle loading. Ref to this link. As you see the Listeners are loaded after the ServletContext is loaded when application starts. You can have your code in the listener class that extends ServletContextListener. Ensure you are extending correct Listener as given in the link.
In your situation, One of the alternative is to have a Singleton class load all the properties from the properties file. for ex: ApplicationPropertiesLoader class can have a Properties map attribute to store the key value pairs of that property file. This class can have a getProperty method that always refer to its internal Properties.
In your servlet class refer to this singleton class to load the properties as required.
Speaking of alternatives, it might be worth a thought to use configuration stored in database, at least if you already have a database connection in your application and have control over the database schema.
We use this technique in all our web applications, mainly for two reasons:
Changes to a property can be done during runtime without monitoring file changes, they can be done by the application itself and one does not need to know a path outside of the deployed application.
Properties can have additional information, such as a type (e.g. number, date, string), a default value, a comment or a user who changed it.
For implementing it, you'll create an application-scoped component which accesses the database properties for the rest of the application.

How to re-initialize beans in spring without application server restart

I am programming service for getting data from database and providing them via REST service. It uses spring mvc. My database connection cofiguration is in property file from where it is loaded by spring as a data source bean during context initialization.
Now my problem is - I want to change configuration in properties file (for example change database info) but I can't afford to restart the application server so the new configuration does not load.
How can I re-initialize spring context or some particular beans so the newly defined properties are used?
If you want multiple data source in spring and need to deciding appropriate data source dynamically at runtime you can do this with AbstractRoutingDataSource provided with spring. You have to implement your lookup key logic for determining data-source in method determineCurrentLookupKey(). With this you can map different beans to different data-sources at runtime. following are few questions relating to this context.
How to programatically change databases in Spring with one DataSource?
Also
dynamically change Spring data source

How to implement a resilient bean in Spring?

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.

Tomcat 6 Virtual Hosting Same Spring Application

I want to deploy the same .war file to two different virtual hosts on the same Tomcat 6 instance. However, I am running into a problem with the Spring framework and registering a bean. Here is the error I am seeing...
org.springframework.jmx.export.UnableToRegisterMBeanException:
Unable to register MBean
[com.dti.servlets.Configuration#3a1834]
with key 'EAM:name=webConfig'; nested
exception is
javax.management.InstanceAlreadyExistsException:
EAM:name=webConfig
I am pretty sure that I need to define my contexts for each virtual host but I am not having any luck. The only fix I have found that works is to change the name of the bean key. Any other suggestions would be great.
The problem is that the name of the bean must be unique per JVM. Since you're deploying the same war twice, you have two solutions:
change the registration behaviour of the Spring JMX exporter (see the documentation)
define your own ObjectNamingStrategy to dynamically change the name of the beans at startup (you would end up with names like app1.mybean and app2.mybean)

Categories

Resources