I'm migrating my project's spring XML configuration to #Configuration class and I'm trying to figure out how should I handle bean tags with abstract="true" property. Something like:
<bean id="factoryTemplate" class="com.template.FactoryTemplate" abstract="true">
<constructor-arg index="1" ref="resizerFactory"/>
<constructor-arg index="2" ref="metricFactory"/>
<constructor-arg index="3" ref="settingsDao"/>
</bean>
Clarification: I can't change the XML where the abstract bean is defined because I'm part of a larger project and I'm changing only my modules.
Is there a methodology on how should I do such migration?
Related
I am working on a spring application and need to pass in different implementations of a bean based on envt.
My bean is defined this way:
<bean id="com.myStep"
class="com.myStep">
<property name="onSuccess" ref="com.loadStep"/>
<property name="onError" ref="com.dontLoadStep"/>
</bean>
I need to pass different implementation of loadStep,something like the following during prodction envt :
<bean id="com.loadStep"
class="com.loadStep">
<constructor-arg ref="com.remoteProvider"/>
</bean>
Something like this in dev envt:
<bean id="com.loadStep"
class="com.loadStep">
<constructor-arg ref="com.localProvider"/>
</bean>
I have tried
<beans profile="prod">
<bean id="com.loadStep"
class="com.loadStep">
<constructor-arg ref="com.remoteProvider"/>
</bean>
and for dev:
<beans profile="dev">
<bean id="com.loadStep"
class="com.loadStep">
<constructor-arg ref="com.localProvider"/>
</bean>
I dont have envt specific xml,so i am defining both the profiles in same xml. When i try this,i get an error as the same bean id is used for both dev and prod profiles.
I have this:
<bean class="...">
<constructor-arg name="beans">
<list>
<ref bean="beanA" />
<ref bean="beanB" />
</list>
</constructor-arg>
</bean>
I want to configure the list via a properties file, something like:
Properties file:
beans=beanA,beanB
XML file:
<bean class="...">
<constructor-arg name="beans">
<list refs="${beans}" />
</constructor-arg>
</bean>
Is something like this possible with Spring?
Edit: Just to give some context in case there are alternative solutions to the problem, this is for an application that has to write to multiple databases, and I want to configure which databases are enabled in the properties file, so that I don't have to maintain separate XML files for dev/production.
My first though is to use a FactoryBean where you inject the property ${beans} and the application context. Then in the factory bean, you loop on on every bean id/name and you call the context to retrieve the bean by name/id. Then you constructs your bean with your constructor and the list you have just built.
use annotation i.e.
#Value("${beans}")
private Class<? extends YourBean>String[] beanList;
Hi All in my Spring application i have used AutoWired NamedParameterJdbcTemplate.
#Autowired
NamedParameterJdbcTemplate namedParametersJdbcTemplate;
in my rest-servlet.xml
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/mylfrdb"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource"/>
</bean>
<bean class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate" id="namedParameterJdbcTemplate">
<constructor-arg ref="jdbcTemplate"></constructor-arg>
</bean>
<bean class="org.springframework.jdbc.core.simple.SimpleJdbcCall" id="simpleJdbcCall">
<constructor-arg ref="dataSource"></constructor-arg>
</bean>
It working fine.
No i have to use performance intercepter with Spring AOP.
So i added following thing in my rest-servlet.xml
<aop:config >
<aop:pointcut expression="#target(org.springframework.stereotype.Service)" id="allServices"/>
<aop:advisor pointcut-ref="allServices" advice-ref="perfMonitor"/>
</aop:config>
So i got error like this.
Can not set org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate field com.lfr.dao.impl.FlatAdvertiseDaoImpl.namedParametersJdbcTemplate to com.sun.proxy.$Proxy15
So i refered this question and tried to implement 2nd solution give is by using CGLIB and
<aop:config proxy-target-class="true" >
No i am getting this error
Could not generate CGLIB subclass of class [class org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
I had the exact same error message. I was using Spring 3.2.5.RELEASE version. After debugging and trying to repeat the problem with PetClinic example came out it was matter of Spring version. This problem didn't occur in Spring 4.1.1. Try to upgrade, maybe it works.
Suppose I have my own bean which contains another beans hardcoded.
How to join this with Spring configuration?
First way is to use factory-method:
<bean id="bean1" class="myClass1"/>
<bean id="bean1.member" factory-bean="bean1" factory-method="getMember"/>
<bean id="bean2" class="myClass2">
<property name="collaborator" ref="bean1.member"/>
</bean>
Another way is to use EL:
<bean id="bean1" class="myClass1"/>
<bean id="bean2" class="myClass2">
<property name="collaborator" value="#{bean1.member}"/>
</bean>
In latter case Spring does not realize the dependency. Anyway, Bean Graph in Eclipse displays beans unrelated.
Are there better ways? May be I may implement some interface with MyClass1 so that it will treated as container or context?
You should create a separate bean for bean1.member and inject it into bean1
<bean id="bean3previouslyMember" class="myCompoundBean"/>
<bean id="bean1" class="myClass1">
<property name="member" ref="bean3previouslyMember"/>
</bean>
<bean id="bean2" class="myClass2">
<property name="collaborator" ref="bean3previouslyMember"/>
</bean>
Unless myClass1 is not modifiable and has no setter, this is generally what we do.
I've created a few beans for validation of an object:
<!-- RES rules engine -->
<bean id="rules-execution-server-engine"
class="util.res.RuleEngineRESJSE">
<constructor-arg index="0" value="util.res.rulesengine.log" />
</bean>
<bean id="rio-object" class="UROImpl">
</bean>
<bean id="trade-validator-context"
class="rule.trade.TradeValidationContext">
<constructor-arg index="0" ref="rio-object" />
</bean>
<bean id="trade-validator"
class="validator.RESTradeValidator">
<constructor-arg index="0" ref="trade-validator-context" />
<constructor-arg index="1" ref="validation-rules-helper" />
</bean>
<bean id="validation-rules-helper"
class="util.res.RESRulesHelperImpl">
<constructor-arg index="0" value="rule.traderules.loc" />
<constructor-arg index="1" ref="rules-execution-server-engine" />
</bean>
I can call and create them through a main method sucessfully.
However I am now trying to integrate this code within my other modules.
The trade-validator bean implements a interface which looks like:
public interface IValidator {
public Object validate(Object obj) throws ValidationException;
}
I am hoping to call this via the interface:
validator.validate(rioObject);
However this is causing issues as I cannot instanate the interface and from the XML you can see the actual requires two other beans for it's constructor. I've been looking at the autowired approach. But am still getting to grips with it.
Is there a way to point it towards the bean as being the validator to use? As atm the validator is null.
My recommendation is to avoid using autowire for bigger deployments and wire the beans yourselves.
BTW, why are you not able to instantiate the trade validator ? What is the error that you are getting?
However this is causing issues as I cannot instanate the interface and
from the XML