Spring - List references a DOA method to get its values - spring

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.

Related

Spring bean creation

Is it possible to create to bean with same id with same class with different property in spring ? Like:
<bean id ="a" class= "com.tofek.A"
<property message = "khan"/>
</bean>
<bean id = "a" class = "com.tofek.A"
<property message="tofek"/>
</bean>
As per my understanding it will create, but while fetching the bean using getBean() method it will give exception like NoBeanDefinitionFoundException.
Please correct my understanding if I'm wrong?
Make sure your spring context is loaded sucessfully.
Answering your question. You can have two identical bean definitions in two different sprintContext configurations.
The bean from second context will override bean created by first one.
For example :
context1.xml
<bean id="bean1" class="org.springframework.beans.TestBean"/>
context2.xml
<bean id="bean1" class="org.springframework.beans.TestBean"/>
then, the bean from context2.xml will override bean created by contex1.xml.
It of course depends on order of creating spring contexts. The laters overrides the ones made before.
You can use getBean() to fetch bean by type or name. In this case, both bean have same id's and types, the spring wouldn't know which one you want to fetch.

overriding bean configuration in spring

Let's say I have two modules. One is core and another is core dependent implementation module.
Core is a jar file for that dependent implementation module war.
In the core I have a bean defined like
<bean id="x" class="com.pokuri.X">
<property name="y" ref="y"/>
<property name="z" ref="z"/>
</bean>
And that class has a method as follows
public class X{
public void doSomeJob(){
.......
}
}
this method is being called from some core classes. Now I need to alter the logic in that doSomeJob() method of X as per my core dependent implementation. So, I create a class like this
public class ExtX extends X{
#override
public void doSomeJob(){
// changed logic
}
}
and defined the bean with same id in another application context xml file like this.
<bean id="x" class="com.pokuri.ExtX">
<property name="y" ref="y"/>
<property name="z" ref="z"/>
</bean>
and we are building application context using contextConfigLocation context parameter in web.xml specifying value as classpath:springfolder.
But in the core logic I am getting core bean instance only(i.e X instance) not ExtX. How can we override that bean definition and let system start using new extend bean definition?
And I heard that with same ID in different application context files will override first loaded bean definition with later loaded bean definition. Is there any priority kind of attribute on bean definition to let ApplicationContext use highest priority one to consider over low priority one when beans with same ID were found.
One way of overriding the bean definition is what you have indicated - to define it with the same id multiple times and the last bean definition with the same id is the one which takes effect. So if you ensure that ExtX is the last one loaded up, it should just work, and to ensure this you can do this in your war file, instead of loading up by saying classpath:springfolder, you can explicitly import the core configuration in your war's Spring config file and then override the bean this way:
<import resource="core-resource.xml"/>
<bean id="x" class="com.pokuri.ExtX">
<property name="y" ref="y"/>
<property name="z" ref="z"/>
</bean>
This will ensure that your overridden bean is the one which takes effect.
There is no priority/order field that you can make use of here though - if you want you can load up all bean definitions of a type by providing Map<String,X> as a parameter, and sort it by expecting an order property and use it that way, but there is lot more work to it.
A second approach is described here: Overriding the bean defined in parent context in a child context

looking up beans from resources.xml into controller/service in groovy

I am using groovy-grails with jasper reports to develop an app. I need to lookup 'report bean' based on its parameter (like reportname /id retrived from database, which I will get from customer click) - which will be stored as a property of report bean from resources.xml into either the reportcontroller or reportservice. Also I have to 'get' the jrxml template related to this id and the parameter Map, both defined as properties in the bean. I need to know like how can we achieve this and do we need to define any 'managing beans' in the xml which manage these report beans.
So for example the report bean will look like as follows:
<bean id="DeptReport" class="com.myapp.reporting.domain.Report">
<property name="reportName" value="Dept Report"/>
<property name="reportFiles">
<map>
<entry key="JasperPrint" value="DeptRoles.jrxml"/>
</map>
</property>
<property name="promptforparameter" value="true"/>
<property name="parameter" value="department_id"/>
<property name="displayName" value="report.deptReport.name"/>
</bean>
There will be many beans like this.
Also the .jrxml file for all reports are stored in a directory and I want to wire that location into the reporting context so that whenever a report is clicked on the front end I want to look up these values from the context into the report service/controller to generate the report. I know we have to do like a ctx.getbean(reportId) somewhere but I also want to know how to setup a manager bean with some other properties like template location, datasource, parameter map, reportid and a jasperreportrenderrer object. So this ReportManager bean is loaded reused every time there is a call for another report and persisted across a user session ideally.
You should be able to do something like this:
import org.springframework.context.*
class MyService implements ApplicationContextAware {
ApplicationContext applicationContext
def getBeanByName( String name ) {
applicationContext.getBean( name )
}
}
That's in a grails Service class, but the same should hold true for a controller

Spring Dependency injection scope confusion

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.

Create bean of type Set<Class<?>>

How can I create a bean of type Class?
I found a way using getClass() but that requires an instance and cannot be used via factory-method since it is not static. It also requires an extraneous bean be created for this express purpose:
<bean id="foo" class="Foo" />
<bean id="fooClass" factory-bean="foo" factory-method="getClass" />
This isn't so bad if the Foo class is easy to construct, but what if the constructor has required parameters?
I then need to create a Set of Class to wire into another bean via a property. I would create the Set such as:
<util:set id="classSet">
<ref local="fooClass"/>
</util:set>
If you really wanted to do what you describe, then you can do it like this:
<bean id="myClass" class="java.lang.Class" factory-method="forName">
<constructor-arg value="com.MyClass"/>
</bean>
But as #ChssPly76 said, if you want to inject it into another bean, you only need inject the class name, and Spring will auto-convert it into a class instance for you.
Why would you? Can you provide an example where that's actually needed?
If you only need this as a dependency (e.g. some other bean has a property of type Class), Spring's built-in ClassEditor property editor would convert a regular string into a Class instance with that name for you:
<property name="someClass" value="java.lang.String"/>
The above would result in setSomeClass(Class clazz) setter being called on the bean whose property that is.

Resources