getting new bean instances of referencing beans every time - spring

I have two queries ...
1) I have a query that beans are intialized in the spring container itself when the spring container is intialiazed and before the call is made to the get bean() method , this is the default behavior , how can I configure the application in such way that bean should be initalized in container only when a call is made of getbean() is made, shall we declare the bean as prototype to achieve this.
2) second query is that first please go through the below example first...
<beans>
<bean id="triangle" class="Demo.Triangle" scope="singleton" >
<property name="pointA" ref="zeropoint"/>
<property name="pointB" ref="firstpoint"/>
<property name="pointC" ref="secondpoint"/>
</bean>
<bean id="zeropoint" class="Demo.Point" scope="prototype" >
<property name="x" value="10" />
<property name="y" value="20" />
</bean>
<bean id="firstpoint" class="Demo.Point" scope="prototype" >
<property name="x" value="10" />
<property name="y" value="20" />
</bean>
<bean id="secondpoint" class="Demo.Point" scope="prototype">
<property name="x" value="10" />
<property name="y" value="20" />
</bean>
As indicated above that triangle bean is singleton and it references bean are protoype now when I access singleton the other refernces beans zeropoint,firstpoint and secondpoint are also initaizes only once with respect to triangle but Here I want that every time new instance of these three beans to be get created when the triangle bean is fetched , Please advise how that is achieable. is it achievable through my pojo implementing ApplicationContextAware interface, Please advise

Instead of relying on Spring infrastructure (BeanFactoryAware) I recommend trying lookup method feature:
abstract class Triangle {
public abstract Point createZeroPoint();
public abstract Point createFirstPoint();
public abstract Point createSecondPoint();
public void foo() {
Point p0 = createZeroPoint();
Point p1 = createFirstPoint();
Point p2 = createSecondPoint();
}
}
Every time you call create*Point() abstract method, it creates new instance of Point. But how do you implement this method and how does it know which bean to return? Spring implements this for you!
<bean id="triangle" class="Demo.Triangle" scope="singleton">
<lookup-method name="createZeroPoint" bean="zeropoint"/>
<lookup-method name="createFirstPoint" bean="firstpoint"/>
<lookup-method name="createSecondPoint" bean="secondpoint"/>
</bean>
Check out the comprehensive documentation: 4.4.6.1 Lookup method injection.

Its called Lazy loading
<bean id="myBean" class="a.b.MyBean" lazy-init="true"/>
First note that your firstpoint and secondpoint beans don't have a valid scope definition (you missed the scope=)
Prototype scope means that every bean that requires a prototype bean gets its own instance. If would define multiple triangles which all have a dependency to zeropoint every triangle would a separate zeropoint instance.
If you need new point instances inside your triangle class (e.g. every time you call a method of triangle) the best way is to receive instances directly from the bean factory:
E.g.
class MyClass implements BeanFactoryAware {
private BeanFactory beanFactory;
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public void doSomethingThatRequiresNewInstance() {
Triangle t = beanFactory.getBean("zeropoint", Triangle.class);
// because zeropoint is defined as prototype you get a new instance everytime you call getBean(..)
}
}

Related

Spring: Setting a property annotated with #Resource

This following does not behave like I expect, using Spring 3.2.1.RELEASE, groovy 1.8.8. I've elided quite a bit of code. If this isn't sufficient, I'll put together a (not) working full example.
groovy bean:
package foo
import javax.annotation.Resource
class SomeBean {
#Resource
String someProp
}
spring xml:
<context:annotation-config />
<context:component-scan base-package="other.packages.not.foo" />
<bean id="someBean" class="foo.SomeBean">
<property name="someProp" value="bar" />
</bean>
This fails with an error about not being able to find a bean to satisfy the String property. To work around this, I ended up doing this:
groovy bean:
#Resource( name = 'someProp' )
String someProp
spring xml:
<bean id="someProp" class="java.lang.String">
<constructor-arg value="bar" />
</bean>
<bean id="someBean" class="foo.SomeBean" />
I don't like this solution, because it couples the bean source code to the spring config, and that's coupling in the wrong direction. And it creates an unnecessary bean for a simple String. Am I missing an obvious solution?
#Resource is not meant for property injection.
For this to work:
<bean id="someBean" class="foo.SomeBean">
<property name="someProp" value="bar" />
</bean>
you need to implement a setter method
public void setSomeBean(String value) {
someValue = value;
}
#Resource could be used if you want to inject a different bean from your context.
#Resource(name="someBean")
SomeBean someBean

JSF ManagedBean - injected properties not working correctly on STATE_SAVING_METHOD=client

I am into a problem from two days and I can not get out from this.
The problem I am having is using a MangedBean property after the deserialization (I guess).
The property (purchaseManager) is set up with Spring, and use a DAO which extends MyBatis as data mapper to interact with the DB.
In fact, on the first access to the page, purchaseManager.getAll() inside init() method works fine.
When i try to call refreshList() as an action from a button, I have a NullPointerException on the getSqlSession() inside the DAO.
Letting only the relevant code the situation is as follow:
#ManagedBean(name = "purchaseController")
#ViewScoped
public class PurchaseController implements Serializable{
#ManagedProperty(value = "#{purchaseManager}")
private PurchaseManager purchaseManager;
#PostConstruct
public void init(){
purchaseManager.getAll();
}
public void refreshList(){
purchaseManager.getAll();
}
}
public class PurchaseManagerImpl implements PurchaseManager, Serializable {
PurchaseDAO purchaseDAO;
public void getAll() {
purchaseDAO.getAll()
}
}
public class PurchaseDAOImpl extends SqlSessionDaoSupport implements PurchaseDAO, Serializable {
public void getAll() {
SqlSession session = getSqlSession(); // when the call comes from refreshList(), session is null
session.selectList("PAYMENT.getAll", null);
}
}
in web.xml
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
If I change the STATE_SAVING_METHOD to server the application works fine but is not what I want. Same thing if I make the ManageBean as RequestScope but this too will penalize my requirements.
Thank you in advance to anyone for any kind of help!
Ermal
Solved the error adding <aop:scoped-proxy proxy-target-class="false" /> to the definition of the service/manager declared through Spring. This makes possible the injection of a fully serializable proxy instance.
<bean id="purchaseManager" class="al.ozone.bl.manager.impl.PurchaseManagerImpl">
<property name="purchaseDAO" ref="purchaseDAO" />
<aop:scoped-proxy proxy-target-class="false" />
</bean>
proxy-target-class="false" is for telling that PurchaseManagerImpl implements already an interface. If setted to true or omitted, CGLIB2 library must be used.
In this way JSF is correctly taking data from DB using Spring+MyBatis.
The mistery (for me) on this point (more theorical) is :
Is MyBatis object (PurchaseDAOImpl) and the dataSource, correctly handled behind the scenes?
Are they recreated or restored on each HTTP request?
Remember that I have STATE_SAVING_METHOD=client and BackingBean as ViewScope. My Goal is to have the server lighter possible because I expect an hight number of user interactions.
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="poolPreparedStatements" value="true" />
<property name="defaultAutoCommit" value="false" />
</bean>
Thank you very much to anyone for some light on this matter!
Consulted links:
Spring session-scoped beans (controllers) and references to services, in terms of serialization
http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-scopes-other-injection
http://www.infoq.com/presentations/Whats-New-in-Spring-3.0

How to add a param to a factory-method of a factory-bean in Spring?

let's say I have a factory bean:
<bean id="myFactory" class="com.company.MyFactory" lazy-init="true">
<property name="myProperty" ref="propA">
</bean>
Let's say propA is a bean injected by IOC used in the factory method. And I have 2 beans generated from this factory:
<bean id="bean1" factory-bean="myFactory" factory-method="instance"/>
<bean id="bean2" factory-bean="myFactory" factory-method="instance"/>
How can I make bean2 to use a different myProperty than bean1 without using a different factory method? Or, how can I pass propA as a parameter to the factory-method from the bean1 or bean2 configuration?
This can be achieved in a slightly different way:
class MyFactory {
public Bean instance(MyProperty myProperty) {
return //...
}
}
Now you can use counterintuitive syntax like following:
<bean id="bean1" factory-bean="myFactory" factory-method="instance">
<constructor-arg ref="propA"/>
</bean>
<bean id="bean2" factory-bean="myFactory" factory-method="instance">
<constructor-arg ref="propB"/>
</bean>
Believe it or not but propA and propB will be used as instance() method arguments.

Datanucleus: moving from #Transactional to non-transactional

I am using Datanucleus, JDO and Spring's declarative #Transactional management woven with Aspect-J.
But when a 'normal' method gets a persistent object from a #Transactional method, the object's state will become transient (the persistence manager seems to be removed) and the object is no longer persistent.
Example:
public class Example {
public void test() throws Exception {
Login l = getLogin();
JDOHelper.getObjectState(l); // transient instead of persistent
l.getSomeOtherPersistentObj().doStuff(); // NullpointerException :(
}
#Transactional
private Login getLogin() {
// do transactional stuff here
// ..
return dao.find(Login.class, 1);
}
}
Why is this and how can I fix it without adding #Transactional in places where transactions are not needed? The following does (obviously) work so this indicates that a transactional as well as a non-transactional connection can be made:
A #Transactional method calls a #Transactional method
A #Transactional method calls a normal method
A normal method calls a normal method
If I call dao.refresh(l), I get: 'Object with id "" is managed by a different Object Manager', so maybe Spring is working on a different persistence manager than the DAO, is this the cause?
Here's my spring configuration (it might be relevant):
<bean id="pmf" class="org.datanucleus.api.jdo.JDOPersistenceManagerFactory" destroy-method="close">
<property name="connectionDriverName" value="com.mysql.jdbc.Driver"/>
...
<constructor-arg>
<map>
<entry key="datanucleus.autoCreateSchema" value="true" />
</map>
</constructor-arg>
</bean>
<bean id="myPmfProxy" class="org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy">
<property name="targetPersistenceManagerFactory" ref="pmf" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jdo.JdoTransactionManager">
<property name="persistenceManagerFactory" ref="myPmfProxy" />
</bean>
<bean id="JDODao" class="sw.JDODao">
<property name="persistenceManagerFactory" ref="myPmfProxy" />
</bean>
It turned out that my objects need to be detachable to do this.
Iv'e added (detachable="true") to my #PersistenceCapable annotations and set the following datanucleus options:
<entry key="datanucleus.DetachAllOnCommit" value="true" />
<entry key="datanucleus.detachedState" value="all" />

Inject spring dependency in abstract super class

I have requirement to inject dependency in abstract superclass using spring framework.
class A extends AbstractClassB{
private Xdao daox ;
...
public setXdao() { ... }
}
class AbstractClassB{
..
private yDao daoy;
public seyYdao() { ... }
}
I need to pass superclass dependency everytime i instantiate Abstract class B (which can be subclassed in 100's of ways in my project)
entry in application.xml (spring context file)
<bean id="aClass" class="com.mypro.A"
<property name="daox" ref="SomeXDaoClassRef" />
<property name="daoy" ref="SomeYDaoClassRef"/>
</bean>
How can i just create bean reference of super class AbstractClassB in application.xml so that i can use it in all subclass bean creation?
You can create an abstract bean definition, and then "subtype" that definition, e.g.
<bean id="b" abstract="true" class="com.mypro.AbstractClassB">
<property name="daox" ref="SomeXDaoClassRef" />
</bean>
<bean id="a" parent="b" class="com.mypro.A">
<property name="daoy" ref="SomeYDaoClassRef" />
</bean>
Strictly speaking, the definition for b doesn't even require you to specify the class, you can leave that out:
<bean id="b" abstract="true">
<property name="daox" ref="SomeXDaoClassRef" />
</bean>
<bean id="a" parent="b" class="com.mypro.A">
<property name="daoy" ref="SomeYDaoClassRef" />
</bean>
However, for clarity, and to give your tools a better chance of helping you out, it's often best to leave it in.
Section 3.7 of the Spring Manual discusses bean definition inheritance.
You can use the abstract flag of Spring to tell Spring that a class is abstract. Then all concrete implementations can simply mark this bean as their parent bean.
<bean id="abstractClassB" class="AbstractClassB" abstract="true">
<property name="yDao" ref="yDao" />
</bean>
<bean id="classA" class="A" parent="abstractClassB">
<property name="xDao" ref="xDao" />
</bean>
Have an abstract parent bean:
http://forum.springsource.org/showthread.php?t=55811

Resources