Spring inject bean is always singleton - spring

We are using spring 3.2.
We defined a bean myAccountVO in spring.xml files and set the scope to prototype, but the spring creates this bean as singleton bean.
Here is the spring xml:
<bean name="myAccountVO1"
class="valueobject.AccountVO"
scope="prototype" >
<property name="accountNo" value="0105069413007" />
<property name="accountType" value="01" />
</bean>
The service class is:
#Service //I've tested the #Scope("prototype") but no luck
public class AccountSummary {
#Autowired //I also tested #Resource but same result
private AccountSummaryVO myAccountSummaryVO1;
AccountSummaryVO getAccount(){
return myAccountSummaryVO1
}
}
Later we use this service as:
#Autowired
AccountSummary accountSummary;
............
accountSummary.getAccount()
As far as I get the AccountSummary class, itself, is a singleton and will not be instantiated every time.
It seems are very basic usecase, but I don't know what am I missing.

I don't see where you are injecting myAccountVO1.
But I guess when you reveal the injected place that it's probably a member of a bean which itself is not in the scope prototype, e.g. #Service or #Controller. The service bean will be instantiated with a newly created myAccountVO1, but this instance stays there forever.
Change the scope of the containing bean. See 4.5.3 Singleton beans with prototype-bean dependencies.
This applies as well to the beans which have the service beans injected.

Related

Initialize bean while project deployment spring

I was asked in one of interview that how we can initialize bean while project deployment in Spring ?
There are several options:
Your bean can implement InitializingBean interface and initialization work can be done inside afterPropertiesSet() method
You can just add a method in a bean class and annotate it with #PostConstruct
You can add method in a bean class and mark it as an init method. Using xml config the bean definition would look like this:
<beans>
<bean id="myBean" class="..." init-method="init"/>
</beans>
And using Java config like this:
#Bean(initMethod="init")
public MyBean myBean() {
return new MyBean();
}
You can also implement your own BeanPostProcessor and provide implementation in postProcessAfterInitialization or postProcessBeforeInitialization methods.
One caveat: all this initialization logic is a part of bean lifecycle, which doesn't mean that it will be invoked during the project deployment.
However if bean is a singleton bean then by default it is created during the spring context start up. I guess it is what you mean by project deployment.

How to inject spring properties into wicket components?

I'm searching for a possibility to inject a property which is defined in a spring context (provided by a propertiesFactoryBean) into a wicket component. I know the way to inject beans into components by using the #SpringBean-Annotation, but whats the corresponding way for properties?
The way my property is defined:
<bean id="myPropertiesFactory" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="mySpringProperty">mySpringProperty</prop>
</property>
</bean>
Things I've tried. The way it works usually with self defined beans:
#Inject
#Value("${mySpringProperty}")
Using the name of the propertiesFactory to access the property value
#Inject
#Value("$myPropertiesFactory.properties.mySpringProperty")
Using the Value Annotation
#Value("#myPropertiesFactory['mySpringProperty']")
Using SpringBean
#SpringBean(name="myPropertiesFactory.mySpringProperty")
None of these solutions works. So to get mySpringProperty injected i use the workaround to create a bean of the type String which get's injected properly by wicket when i annotate the corresponding member of my component with SpringBean but i think there must be a better solution.
<bean id="mySpringPropertyBean" class="java.lang.String">
<constructor-arg type="java.lang.String" value="https://foobar.com" />
</bean>
Annotate
#SpringBean
private String mySpringPropertyBean;
#SpringBean only supports injection of spring beans. I suppose someone could implement a #SpringValue annotation that does what you want, but as far as I know noone ever did.
What I usually do is:
My wicket application class is a spring bean.
It has properties with #Value annotations - as the object is a spring bean, these are evaluated and set properly
I access the actual values by calling MyApplication.get().getXXX() or ((MyApplication)getApplication()).getXXX()
If the app grows and the number of attributes approach a limit, I refactor them into separate Settings or Config classes - each one a spring bean of it's own, accessible from the application class.
In your Wicket class use instead of #Value("${mySpringProperty}"):
#SpringBean
private PropertiesConfiguration propertiesConfiguration;
Create a new PropertiesConfiguration class:
#Component
public class PropertiesConfiguration {
#Value("${mySpringProperty}")
private String mySpringProperty;
//getters & setters
}
Use in your wicket class:
System.out.println("mySpringProperty=" + propertiesConfiguration.getMySpringProperty());

reusing spring beans - name collisions

What is the preffered approach for reusing other jar containing spring-annotated classes in spring (3.2) ?
Example of a problem:
I have a jar that has #Autowired SessionFactory, but it needs different session factory than the rest of the application (it talks to a different database)
So, if I just put that jar in my classpath the application won't start because there are 2 beans with the same type/name. I need to have that jar isolated from the rest of the application.
How to achieve that?
Selecting a particular bean when multiple candidates are present is addressed by #Qualifier. Just declare the same beans in your application context and assign them with different id's or qualifier names. Lets take a look at this class:
public class Foo{
#Autowired
private SessionFactory sessionFactory;
}
Assuming both SessionFactoryImpl1 and SessionFactoryImpl2 are both candidates for bean wiring, and you want to point sessionFactory to SessionFactoryImpl1 instance instead, then you need to add the #Qualifier annotation just like in the example below:
public class Foo{
#Autowired
#Qualifier("sessionFactory1")
private SessionFactory sessionFactory;
}
And in your application context
<bean class="example.SessionFactoryImpl1">
<qualifier value="sessionFactory1"/>
<!-- inject any dependencies required by this bean -->
</bean>
<bean class="example.SessionFactoryImpl2">
<qualifier value="sessionFactory2"/>
<!-- inject any dependencies required by this bean -->
</bean>

spring: need for an example of using prototype bean in a web environment

I wonder how can I properly inject a prototype bean to a singleton one in a web app. Consider this example:
<bean id="order" class="com.foo.Order" scope="prototype"/>
<bean id="orderService" class="com.foo.OrderService">
<property name="userPreferences" ref="userPreferences"/>
</bean>
I thought of using getBean() but isn't that a way to make my code dependent to spring itself?
I need a short java code example to demonstrate how to inject an order bean in my OrderService singleton.
Thanks
You can use jsr-330 Providers, just put:
#Autowired
Provider<Order> orderProvider;
in your singleton bean, and then use the provider:
public Whatever yourMethod() {
Order order = orderProvider.get();
}

Spring injection bind toInstance

Is there a way to bind an injected object to a specific instance using Spring DI similar to Google Guice's
bind(MyClass.class).toInstance(myclassobject);
If the constructor or member variable is annotated with #Autowired, Spring will try to find a bean that matches the type of the Object. You can get similar functionality to the annotation using #Qualifier, for example:
bind(MyClass.class).annotatedWith(Names.named("main")).toInstance(myclassobject);
would become in Spring:
#Autowired #Qualifier("main") private MyClass myClassObject;
<bean name="myClassObject" class="example.MyClassImpl">
<qualifier value="main"/>
</bean>
See http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-autowired-annotation for more.

Resources