Spring Dependency injection scope confusion - spring

I am new to Spring DI and i am implimenting DI for the first time in my webapplication.
it seems i am doing somehing wrong and it related the way i am using spring scope.here is my problem
i have a serive class where i am injecting various other object in order to achieve the desired functionality
here is my spring file entries
<bean id="ImportServiceImpl" class="ImportServiceImpl" factory-method="getInstance">
<property name="browseDirectory" ref="browseDirectoryImpl"/>
<property name="xmlUnmarshaller" ref="xmlUnmarshallerImpl"/>
<property name="Adaptar" ref="AdaptarImpl"/>
<property name="DAOService" ref="DAO"/>
</bean>
<bean id="browseDirectoryImpl" class="BrowseDirectoryImpl" factory-method="getInstance" />
<bean id="xmlUnmarshallerImpl" class="XMLUnmarshallerImpl"/>
<bean id="AdaptarImpl" class="AdaptarImpl" factory-method="getInstance"/>
now in my adaptarImpl class i have a refrence to some other object which is being initialized in the constructor
private AdaptarImpl(){
foo=new Foo();
}
now for the first time when the server start and this service run fist time everything is fine foo is being initilized to its proper initialization value but for all other subsequent calls Spring is returing refrence to the previous initialized foo object where i want that for each new request a new instance of foo should be created.
it apperas to me that the factory method being used in the above code factory-method="getInstance"
is being called only once when server called and all other subsequent calles returning same refrence where i want a new instance for every request.
here is my facory method
public static ImportServiceImpl getInstance(){
return new ImportServiceImpl();
}
i know i am doing basics wrong in DI but not sure where it is.I am using Struts2 for MVC and for service layer using Spring DI
any help in this regard will be helpful
Thanks
Umesh

I'm not sure I understand your question, but it sounds like you ought to ask Spring to inject the reference to Foo into your AdapterImpl and make its scope "request". If you need Spring to control object creation, don't call "new".

I think you need to look at
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes
and look at table 3.3.

Related

Synchronized map in spring configuration .1.2.9

We are using Spring 1.2.9 and we are not able to use map:util
Here is the constructor of code which i have to unit test,
public ViewAction() {
screen = Collections.synchronizedMap(new HashMap());
tab = Collections.synchronizedMap(new HashMap());
}
How can i inject the hashmap and add values to the hashmap in the configuration xml.
NOTE : THE QUESTION IS NOT ABOUT USING HASHMAP. IT IS ABOUT CONFIGURING THE xml file. I tried the following and failed
<bean name="viewactionbean" class="com.test.helper.web.ViewAction">
<property name="screen">
<map>
</map>
</property>
</bean>
Error while i configure the above XML file is,
BeanCreationException: Error creating bean with name 'viewactionbean' defined in class path resource
NOTE : Since i am using Spring 1.2.9, i am not able to use "map:util"
You can solve your problem in two different ways:
You can use synchronized(screen) blocks everywhere you need to access anything in the screen map. That way you don't really need a synchronizedMap as you are already guarding your code anytime you access it.
You can set the synchronizedMap in the setter of your bean, so when Spring injects it you are placing a wrapper around it instead the actual instance provided by Spring:
Example setter method:
public void setScreen(Map screen) {
this.screen = Collections.synchronizedMap(screen);
}
Problem with this last approach is that if you need to perform two or more operations in the map inside a single method in your bean, you still need the synchronized(screen) block to protect from race conditions.
To configure the map in spring you should be able to do this:
<bean id="..." class="....">
<property name="screen">
<map>
<entry key="myKey" value="myValue" />
</map>
</property>
</bean>
You have to use something like this for HashMap.
private static Map<K,V> screen = Collections.synchronizedMap(new HashMap<K,V>);
Than for Thread safety you can use .
synchronized (screen) {
}

Constructors in Bean

I have one small issue with creating a new bean. Basically as per request, I get some parameters, which needs to be passed to a bean. Below I am instantiating ControllerService for each request. Rather I would like it to be a bean with scope=protype. So that I get a fresh object for every request.
But then how do i set the 2 properties (kpiName, kpiInput) that I am sending via constructors in the bean??
#Autowired
#Qualifier("serviceManager")
Cleanser serviceManager;
#RequestMapping(method = RequestMethod.POST)
public #ResponseBody
String getKPIResult(#RequestParam("kpiName") String kpiName,
#RequestParam("kpiInput") String kpiInput) {
return serviceManager.checkAndExecute(new ControllerService(kpiName, kpiInput));
}
In situations like this where you're going against the grain of Spring, I'd suggest that perhaps you're doing something in a way that's not considered best practice. Without more context it's hard to see though.
Spring Social uses a request scope bean to embody a repository for a specific user. I've now idea why as it's a horribly inefficient way of doing things, and much less understandable IMHO.
<bean id="connectionRepository" factory-method="createConnectionRepository"
factory-bean="usersConnectionRepository" scope="request">
<constructor-arg
value="#{T(org.springframework.security.core.context.SecurityContextHolder).getContext().getAuthentication().getPrincipal()}" />
<aop:scoped-proxy proxy-target-class="false" />
</bean>
You can see here the use of factory-bean and factory-method to declare a class/method to call when wanting an instance of your class. The constructor argument is passed using SpEL. I'm not quite sure how you'd achieve this with Spring MVC responding to web requests, but I'm fairly sure you could use Spring Integration to pass a message and use SpEL to grab headers/payload form that message to pass to the constructor.
Again though, I'd really question your design pattern here - a more usual SOA idiom is to create services on startup, and have them as stateless as possible from there-on in, rather than create an instance with specific state for each request. Best of luck!
Don't. The Controller as it's intended in Spring MVC is largely derived from the old Java servlet, which should be stateless by specification.
In fact, Controller-objects are hard-cached inside the handler mapping framework and not fetched from the bean context on each request. Setting scope to "prototype" would, effectively, do nothing as the handler (controller) is really only gotten once.

Spring - List references a DOA method to get its values

I am brand new to spring and I am trying to write my first spring application.
I have set up a DOA class that accesses the DB and pulls a list of values. I would like to reference those values in a bean definition.
For Example:
I have DAO class called "JdbcDataDAO" that contains a method getValues() - I would like to reference the values in a standalone list in my bean definitions
Here is what I have:
<bean id="dataDAO" class="dao.impl.JdbcDataDAO">
<property name="dataSource" ref="dataSource"/>
</bean>
<util:list id="myList" list-class="java.util.List">
<value>#{dataDAO.values}</value>
</util:list>
But when I retrieve the bean "myList", it contains "#{dataDAO.values}" and not the values
Any help would be appreciated - Thanks
Note sure if you can do this with SpEL. And it doesn't look good anyway - you are mixing infrastructure/configuration with business logic.
You can have a factory-bean or a #Configuration class with #Bean methods where you can inject the DAO and programatically populate the list.
You can also have a BeanPostProcessor that takes all List beans an fills them with whatever you want.

MVC Datasource: controller or model?

Just a quick question: In an OOP MVC application, one key principle is the seperation of responsibilities. I therefor think that a model and the object that fetches the model from a database, file, xml, webservice, etc. should be seperated from the model itself. This can for example be done by implementing a datamapper.
However, what do I do when I have a model that can be loaded from different sources? Should the model be in charge of the datasource, or is this the responsibility of the controller?
An simple example could be a config class that can be loaded from a database or a file. Should the controller instruct the datasource, or should the model know when to load the config info from a database or a file?
have used frameworks were the datasource is informed by the controller MachII, Model-Glue (Coldfusion frameworks) and also from the model layer (ColdSpring) - like Spring in Java.
I think the key thing is to use what makes more sense to you, keep the coupling to a minimum and be consistent, meaning don't put datasource or object dependencies in multiple places.
You could also consider using a service type object to abstract the datasource and have it serve either who it likes.
That IOC file could look like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="chartShareObj" class="model.charts.ChartShared" autowire="byType" />
<bean id="trendChartObj" class="model.charts.TrendChart" autowire="byType" />
<bean id="adminRightsDA0" class="org.datamentor.institution.RightsDAO">
<constructor-arg name="dsn">
<value>${dsn_dm}</value>
</constructor-arg>
</bean>
<bean id="assessmentManager" class="model.assessment.Manager">
<constructor-arg name="dsn">
<value>${dsn_au}</value>
</constructor-arg>
</bean>
</beans>
You can see the different datasources specified by args via args defined in a controller.
Based on your situation and response I would suggest looking into dependency injection. You can then let it handle determining which data source to use based on whatever set of variables you want to let it determine things by. This is what I use when I have multiple data sources and want to have the data source determined by some predetermined factors I have chosen.
http://en.wikipedia.org/wiki/Dependency_injection
As to who should handle the injection, I leave that to a repository factory and simply ask for an interface in the controller. The factory then determines based on the dependency injection which repository to provide.
Example:
Dependency Injection in an global Infrastructure class:
Bind<INewsArticleRepository>().ToMethod(context => NewsRepositoryFactory.Create((NewsRepositoryFactory.RepositoryType)Enum.Parse(typeof(NewsRepositoryFactory.RepositoryType), ConfigurationManager.AppSettings["NewsArticleRepositoryProvider"])));
Repository Factory
public static INewsArticleRepository Create(RepositoryType type)
{
switch (type)
{
case RepositoryType.Mock:
return new MockNewsArticlesRepository();
case RepositoryType.Sql:
return new SqlNewsArticleRepository();
default:
throw new NotImplementedException();
}
}
Call in the controller for a repository
private INewsArticleRepository newsItemRepository;
public NewsController(INewsArticleRepository newsItemRepository)
{
this.newsItemRepository = newsItemRepository;
}
They way I do it in Coldbox is using CB's INJECT method in the model. In the cfargument of the constructor, I specify:
<cfargument name="dsn" type="any" inject="coldbox:datasource:dsn">
And that's from specifying the dsn in the coldbox.cfc file, and calling it "dsn". I keep it generic so I can copy this stuff to other projects and only have to change the DSN name in the coldbox.cfc.
But then after doing that, you get the dsn like this:
variables.dsn = arguments.dsn.getName();
I hope this helps, at least a little.
Rob

when spring bean is loaded and if i have a constructor and setters which one will be called first?

This is a basic question - when spring bean is loaded and if i have a constructor and setters which one will be called first?
Thanks
The constructor must be called before any setter methods are called. Use the init-method to tell Spring to invoke some logic after the setters are called:
<bean class="my.CoolClass" init-method="startup">
<constructor-arg value="Foo" />
<property name="bar" value="baz" />
</bean>
Doesn't the constructor have to be called first? The setters are instance methods so that can't called until the object is instantiated.
I don't think Spring provides any guarantees about the order in which setters are called. It would be good practice to make your beans work regardless of which order the setters are called. If you want to do some processing after all the setters have been called, you might find that it's convenient to use a post construction method. Or if you are using XML configuration rather than annotations, an initialization method might suit.
I wrote simple XML config and step through Spring source code in debugger.
Seems that with Spring 3.x it's possible to combine constructor-arg and property in XML bean definition (check doCreateBean in AbstractAutowireCapableBeanFactory.java, which call createBeanInstance - constructor and populateBean next - setters).
See also https://softwareengineering.stackexchange.com/questions/149378/both-constructor-and-setter-injection-together-in-spring/

Resources