Spring jdbctemplate best way - java

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

Related

SpEL: get current bean name during bean instantiation

I am attempting to use SpEL to get the name of the bean currently being instantiated to allow multiple beans of same class to be created with different properties supplied by #PropertySource. I am hoping for something like the following:
public class SampleBean {
#Value("${#{CurrentBeanName}.val}")
private String val
}
Other bean:
public class OtherBean {
#Autowired
#Qualifier(name="BeanA")
SampleBean beanA;
#Autowired
#Qualifier(name="BeanB")
SampleBean beanB;
}
properties file:
BeanA.val=VALUE A
BeanB.val=VALUE B
If I add beanName=BeanA to my properties file, I am able to get this to work with
#Value("${${beanName}.val}")
Any ideas on what to do for #{BeanName}? If this is impossible then so be it, but if it works it would be much cleaner than my current solution.
EDIT:
Or any way to pass a constant from the xml bean definition to SpEL? example:
<bean id="BeanA" class="...">
<property name="prefix" value="BeanA"/>
</bean>
java:
public class SampleBean {
#Value("${#{prefix}.val}")
private String val
}
Any sort of attribute or anything would work
EDIT2:
This is trivial in old XML based config
spring.xml:
<bean id="beanA" class="SampleBean">
<property name="val" value="${BeanA.val}"/>
</bean>
<bean id="beanB" class="SampleBean">
<property name="val" value="${BeanB.val}"/>
</bean>
SampleBean.java:
public class SampleBean {
private String val;
public void setVal (String val) {
this.val = val;
}
}
However when switching to the new #Value annotations to get rid of all the setters, it seems non-singletons with diff properties aren't supported (i.e. no way to dynamically filter #Value arguments on bean creation)
No; it is not possible to reference the current bean.
EDIT
To address your comment below, the Java Configuration equivalent of
<bean id="BeanA" class="com.my.Foo">
<property name="prefix" value="BeanA"/>
</bean>
is
#Bean
public Foo BeanA() {
Foo a = new Foo();
a.setPrefix("BeanA");
}
although, by convention, you'd probably name it beanA.
If you have singleton bean types you could just use a static final variable for the name and then reference that. But the bigger issue is that you will be breaking the Spring inversion of control principals if you begin depending on Spring bean names, which is why this sort of thing isn't done. Pretty much want to focus on creating modules and domains for your project. If you begin accessing components coming from the Spring Context directly (such as the bean name) you will find that your modules will become brittle, hard to change and very hard to reason about as they begin to depend on behaviour from seemingly unrelated modules, such as the Spring Dependency Injection Framework. Although you may have a valid use-case for doing this you just need to be very very careful.

Spring declare component in xml

I am mostly using #Autowired and #Component annotations in my project. However, I am going to use DataSource class for database actions.
So, I use this is in my dispatcher-servlet.xml :
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/market"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
In my dao class, My setter for the dataSource is :
#Autowired
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
this.jdbcTemplateObject = new JdbcTemplate(dataSource);
}
However this is not doing the trick. My jdbcTemplateObject is null.
If I dont use "context:component scan ..." and use classical spring beans instead, without utilizing #Autowired annotation, all works good.
I can use my database. However, I dont want to declare all the beans one by one in my xml file. As the project grows, it is not going to be practical. How can I solve this problem ? Is it possible to declare dataSource in my dispatcher-servlet.xml as component, so #Autowired works on dataSource ?
When you use #Autowired on fields Spring will look for dependencies and inject them right there there is no point if setter method here.
You do not need to worry about how spring is going to inject the dependency. It will take care of complete life cycle.
For more on Spring's Dependecy Injection visit this link.
You have annotated the field with #Autowired which tells spring to inject the dependency directly into the field. If you really want to use the setter annotate the setter with #Autowired instead of the field.
#Autowired
public void setDataSource(DataSource ds) { ... }
However I strongly suggest to not create a JdbcTemplate for each bean that needs one (it is quite heavy to create). The JdbcTemplate is a thread-safe object, once constructed. So instead of creating a new one for each bean that needs one (in the setDataSource method) just create a single JdbcTemplateand inject that.
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
Then in your dao.
#Autowired
private JdbcTemplate jdbcTemplate;
Or what I like to do..
private final JdbcTemplate jdbcTemplate;
#Autowired
public YourRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate=jdbcTemplate;
}
This way you cannot construct an illegal object, whereas with setter based injection you could. While maintaining the possibility to inject one for testing purposes.
Another note, the DriverManagerDataSource is nice for testing but not for production usage, for that use a real connection pool like HikariCP or Tomcat JDBC.

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.

Scope of Spring beans enforcement

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.

spring3.0 annotations

I have a property file converterValues.properties having these data valueOne=1,valueTwo=2
i am trying to use the annotation
#Value("#{converterValues.valueOne}")
private transient String dataValue;
I want to load all the properties at once not each at a time using converterValues.valueOne
let me know how to get valueOne=1,valueTwo=2 at once using annotation.
I want to avoid defining #value for each key.
First create a qualifier annotation, let's call it #ConverterValues.
Then declare a bean of type PropertiesFactoryBean with the given qualifier.
<bean id="converterValues" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:path/to/properties" />
<qualifier value="your.package.ConverterValues" />
</bean>
Now you can inject the properties into your bean:
#Autowired
#ConverterValues
private Properties converterValues;
Update
You could, of course, skip the overhead of defining a qualifier if you are willing to express the dependency explicitly:
#Autowired
#Qualifier("converterValues") // the name of the bean to inject
private Properties converterValues;

Categories

Resources