Scope of Spring beans enforcement - java

I have a scenario for example.
<bean id="xyzService" class="XyzServiceImpl" scope="prototype">
<property name="aDependency" ref="aDependency" />
<property name="bDependency" ref="bDependency" />
</bean>
<bean id="useService" class="UseServiceImpl">
<property name="xyzService" ref="xyzService"/>
</bean>
Java Class :
public class XyzServiceImpl implements XyzService{
private ADependency aDependency= null;
private BDependency bDependency= null;
// getters and setters...
}
public class UseServiceImpl implements UseService {
private XyzService xyzService= null;
// getters and setters...
xyzService.doSomething();
}
Now every time inside the UseServiceImpl I expect a new Instance of xyzService, but i always return the same singleton instance. Also there is a scenario that the aDependency and bDependency may internally have again some more references to other beans.
Now I have a question like how do I get an new Instance of xyzService. Am I doing something wrong?

By default scope of spring bean is singleton , You need to mark the scope prototype to instruct spring
<bean id="beanId" class="some.class.Name" scope="prototype"/>
Spring will create new instance on each request of Bean
See
bean scopes

I could easily find the solution by implementing the ApplicationContextAware Interface which has the getter and setter method for context. From the context I can say getBean and get the new Instance
public class UseServiceImpl implements UseService,ApplicationContextAware {
private ApplicationContext context;
XyzService xyzService= context.getBean(XyzServiceImpl.class);
// getter and setter for applicationContext
private XyzService xyzService= null;
// getters and setters...
xyzService.doSomething();
}

If you have the following:
<bean id="xyzService" class="XyzServiceImpl" scope="prototype">
<property name="aDependency" ref="aDependency" />
<property name="bDependency" ref="bDependency" />
</bean>
<bean id="useService1" class="UseServiceImpl">
<property name="xyzService" ref="xyzService"/>
</bean>
<bean id="useService2" class="UseServiceImpl">
<property name="xyzService" ref="xyzService"/>
</bean>
Then you should be able to verify that the xyzService property for useService1 and useService2 do contain different instances of xyzService. That's the effect of declaring xyzService to be scoped as a prototype. If you really want new instances of the xyzService bean to be available during the lifetime of the useService bean, I think you'll need a different approach - take a look at the documentation for Method injection.

In your example, every time you request spring container an instance of userService, it will return the singleton instance and injecting a new instance of xyzService.
However, when spring creates a new instance of xyzService, it will use the singleton instance of aDependency and bDependency unless otherwise they are also defined as prototype.

Related

Spring jdbctemplate best way

The spring.xml
<bean id="jdbcTemp" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="portalDataSource" />
</bean>
In class
#Repository
public class DBUtil{
private static final long serialVersionUID = -6203751104015962909L;
#Autowired
JdbcTemplate jdbcTemp;
private static Logger log = Logger.getLogger("scmLogger");
#Transactional(readOnly=true)
public List<Map<String, Object>> getData(String qry, Object[] pAttr){
log.debug("DBUtil.getData() qry "+qry);
List<Map<String, Object>> vList = new ArrayList<Map<String,Object>>();
vList = jdbcTemp.queryForList(qry, pAttr);
return vList;
}
I would like to know if this "jdbcTemplate" is a singleton i.e a single instance in my application. Is this the best way to use or any other way which will be better. Please suggest.
Regards
Adeeb
Though i am not a Spring pro, yes this jdbcTemplate is a singleton. Every bean managed by Spring is singleton unless specified otherwise. And there is nothing wrong with this usage.
When you define a bean in Spring, it has a singleton scope by default.
In your case, you are not defining a different scope so it's singleton.
http://www.tutorialspoint.com/spring/spring_bean_scopes.htm
Yes by default all beans in spring are singleton to make sure you can specify it in bean tag
<bean id="jdbcTemp" class="org.springframework.jdbc.core.JdbcTemplate" scope="singleton">
<property name="dataSource" ref="portalDataSource" />
</bean>
in your class you are auto wiring it, and its the best way to do it. make sure your id in xml and instance variable name is same, in your code its correct jdbcTemp

How to autowire a class with non-empty constructor?

I'd like to #Autowired a class that has a non-empty constructor.
Just the the following as an example, it does not necessairly have to be a view/service. Could be whatever component you like, having non-default constructor:
#Component
class MyViewService {
//the "datasource" to show in the view
private List<String> companies companies;
private MyObject obj;
public MyViewService(List<String> companies, MyObject obj) {
this.companies = companies;
this.obj = obj;
}
}
Of course I cannot just write
#Autowired
private MyViewService viewService;
as I'd like to use the constructor with the list. But how?
Are there better approaches than refactoring these sort of constructors to setters? I wouldn't like this approach as ideally the constructor forces other classes to provide all objects that are needed within the service. If I use setters, one could easily forget to set certain objects.
If you want Spring to manage MyViewService you have to tell Spring how to create an instance of it. If you're using XML configuration:
<bean id="myViewService" class="org.membersound.MyViewService">
<constructor-arg index="0" ref="ref_to_list" />
<constructor-arg index="1" ref="ref_to_object" />
</bean>
If you're using Java configuration then you'd call the constructor yourself in your #Beanannotated method.
Check out the Spring docs on this topic. To address a comment you made to another answer, you can create a List bean in XML as shown in the Spring docs. If the list data isn't fixed (which it's probably not) then you want to use an instance factory method to instantiate the bean.
In short, the answers you seek are all in the Spring docs :)
If a component has a non-default constructor then you need to configure the constructor in the bean configuration.
If you are using XML,
it might look like this (example from the spring reference document):
<beans>
<bean id="foo" class="x.y.Foo">
<constructor-arg ref="bar"/>
<constructor-arg ref="baz"/>
</bean>
<bean id="bar" class="x.y.Bar"/>
<bean id="baz" class="x.y.Baz"/>
</beans>
The key here is constructor wiring of the bean that will be used for the #AutoWire.
The way you use the bean has no impact.

Spring:autowired field is null

I need to wire external lib class to my bean,in order to use it as singleton.
.xml config:
<bean id="myBean" class="com.my.MyBean">
<property name="someLib" value="com.ExternalBean" />
</bean>
java bean:
#Service
public class MyBean {
#Autowired
private ExternalBean externalBean;
public void setExternalBean(ExternalBean externalBean) {
this.externalBean = externalBean;
}
Further I use wired variable externalBean in public method ,in order not to instantiate it in every method call.
Problem is it null.
Do I wire bean correctly?What is mistake.
You have to define the external class as a bean in order to make #Autowired work.
<bean id="externalBean" class="some.external.package.ExternalBean">
</bean>
<bean id="myBean" class="com.my.MyBean">
</bean>
Also, if you use #Autowired you don't need the setter for it.
loodakrawa is right. A second thing that can cause a problem is, that you have a xml bean declaration for myBean and additional annotated the bean with #Service. I guess this will cause trouble as soon as use enable component scan.
I think that the better ide ais to use context path scan:
<context:component-scan base-package="some.external.package">
</context:component-scan>
Make sure that all these classes are within the package. Then mark both classes with one of the Annotations (#Repository, #Service, #Component).
One of the benefits, no setter required.
P.S: If you re using scan base you don't need to declare class as bean, annotations are enough

Spring beans with scope prototype

Suppose have following beach definition:
<bean id="singletonBean" class="...">
<property name="instanceBean" ref="instanceBean"/>
</bean>
<bean id="instanceBean" class="..." scope="prototype"/>
When I call:
singletonBean = context.getBean("singletonBean");
...some code...
singletonBean = context.getBean("singletonBean");
Would property instanceBean of singletonBean be initialized again or it would just use already created singleton?
Would just use already created singleton.
A prototyped inner bean of a singleton won't be recreated each time you get the singleton from context. The singleton and all is references are created one for all.
But context.getBean("instanceBean"); would give you a new since scope is 'prototype'.
instanceBean is set only once on startup, so you can get the instanceBean by singletonBean.getInstanceBean() if you like.
When invoked context.getBean("singletonBean") always it contains the same instance of instanceBean, though the scope is prototype in the bean definition.
On the contrary if the container bean is of scope prototype and it refers to a bean which is defined with scope singleton, always the inner bean would be singleton. Eg:-
<bean id="outer" class="OuterBean" scope="prototype">
<property name="innerBean" ref="inner" />
</bean>
<bean id="inner" class="InnerBean" scope="singleton"/>
OuterBean outer1 = (OuterBean) context.getBean("outer");
OuterBean outer2 = (OuterBean) context.getBean("outer");
Here both outer1 and outer2 will contain same instance of InnerBean.
In a multitheaded environment, if innerBean holds any shared data, it can lead to race condition.

Spring prototype beans in combination with singleton beans and dependency injection. Is there an approach that is configuration only?

I have a singleton bean which needs for each call of a function to return a reference to a different (new) prototype bean. The only way that I can think of doing this is to programmatically retrieve a new prototype bean instance from the BeanFactory/ApplicatioContext by invoking its getBean() method. Code sample will follow...
Is there a better way to do this? Only via configuration, hopefully? (Personally, I doubt there is...)
<bean id="protoBean" scope="prototype"
class="com.blahblah.ProtoBean" />
<bean id="singletonBean"
class="com.blahblah.SingletonBean" />
public class ProtoBean {
....
}
public class SingletonBean {
private BeanFactory factory;
public ProtoBean dispense() {
return (ProtoBean) factory.getBean("protoBean");
}
....
}
take a look at Method Injection
From Spring 3.0, we can use <aop:scoped-proxy> for dependency injection of the proper scope. Behind the scene, Spring injects proxied objects and is responsible for finding the right scope context, may it be prototype, session or request etc. See the official documentations here.
And to make life easier, Spring has also introduced proxyMode attribute for #Scope, so we are not limited to XML declarations only. For example:
#Scope(value = "prototype", proxyMode = ScopedProxyMode.INTERFACES)
Make sure to document clearly the injected bean is a proxy to warn others that getClass() and casting may not yield the expected result. Also, make sure equals() and hashCode() in the proxied class use access methods rather than directly accessing class variables.
Using method injection makes the singleton-bean class difficult to unit-test (you need to create a subclass to implement the method which gives out the dependency). Plus it's less reusable because you can't directly instantiate it, so if you're not using Spring and want to use this class, you'll need to subclass and provide the bean-returning method.
A better approach IMHO is to use a proxy, a prototype target source and a prototype target bean, as follows. Such a singleton-bean class is easily unit-testable and better reusable.
<bean id="targetPooledObject" class="pool.PooledObject" scope="prototype">
<constructor-arg value="42" />
</bean>
<bean id="prototypeTargetSource" class="org.springframework.aop.target.PrototypeTargetSource">
<property name="targetBeanName" value="targetPooledObject" />
</bean>
<bean id="pooledObject" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource" ref="prototypeTargetSource" />
</bean>
<bean id="poolConsumer" class="pool.PoolConsumer">
<property name="pooledObject" ref="pooledObject" />
</bean>
Now we can inject pooledObject into a singleton bean (poolConsumer as shown above), and for every method call that we make on that singleton bean, (e.g. every time we call poolConsumer.callPooledObjectMethod() which in turn calls pooledObject.foo()) we get a new PooledObject bean.
Following is the corresponding code:
public class PooledObject
{
private int x;
public PooledObject(int x)
{
this.x = x;
}
public void foo()
{
System.out.println("foo called");
}
}
public class PoolConsumer
{
private PooledObject pooledObject;
public PooledObject getPooledObject()
{
return pooledObject;
}
public void setPooledObject(PooledObject pooledObject)
{
this.pooledObject = pooledObject;
}
public void callPooledObjectMethod()
{
pooledObject.foo();
}
}

Categories

Resources