Is it OK to define RowMapper class as spring bean? - spring

On many tutorial/books about spring JDBC, RowMapper class usually represented as private static final class inside DAO and the instance is created in every single query.
Does RowMapper have to be used and instantiate in this way?
Is it ok if I define RowMapper class as spring bean using #Component annotation and #Autowired it to my dao class?
Which one is better?

Does RowMapper have to be used and instantiate in this way
No, that's just a common usage pattern.
Is it ok if I define RowMapper class as spring bean using #Component annotation and #Autowired it to my dao class?
Sure, that would work. Unless the RowMapper needs access to other Spring services, though, there's not much point.
Which one is better?
Without seeing your code and getting a feel for your application, we can't really tell you if it's a good idea or not, only you can make that choice.
My personal preference would be to keep the RowMapper as a non-static inner class of your DAO class, and to insantiate it directly from the DAO. If the RowMapper needs access to other Spring beans, then wire those intop the DAO, and access them from the RowMapper inner class.

Related

Why do we use #Autowire

I am new to Spring so my understanding of it is very superficial, nevertheless, suppose we are looking at the following example:
class serviceImpl implements service{
#Autowired
private Mapper mapper;
public void executeService(){
mapper.executeSerice();
}
}
So, I am trying to build some service, which calls mapper from the persistence level. Mapper is an abstract class. So from my understanding, #Autowired will automatically injects one implementation of Mapper here.
Then my question is:
What if there are multiple implementations of Mapper? After some search, it seems that in this case one needs to use #Qualifier to designate which implementation we want to use.
Suppose we are using the implementation powerfulMapper, then we will need to use #Qualifier('powerfulMapper').
Then how is this different from just instantiating Mapper powerfulMapper here?
If you have only one Mapper , you only need #Autowired to inject. If there are more than one Mapper implementation registered as Spring bean , you have to use #Qualifier or #Resource to tell Spring which implementation you want to inject. See this for more details.
Then how is this different from just instantiating Mapper
powerfulMapper here?
The difference is that if a class is a Spring bean , we can apply some Spring feature on it such as :
Apply some AOP magic on it such as #Async , #Transactional , #PreAuthorize etc.
Think about the case that if a class has a lot of dependencies which in turn has a lot of dependencies, creating an instance of this class configuring with the whole dependency graph is not an enjoyable thing to do . Not to mention different dependency can has different requirements (e.g. one may needed to be instantiated as a singleton and will be shared to be used by different class while other may need to be in the prototype scope which different classes need a separate instance etc.)
Using #Autowired and let spring to configure such dependency graph is more easier than do it manually.
On the other hands , if the Mapper has very simple dependencies , only used internally inside ServiceImpl and you don't need any benefit provided by spring on it , you can simply instantiate it without declaring it as spring bean.
Dependency Injection (DI) is so that you avoid having a complicated tree of dependencies.
Imagen having a tree like structure where A instantiates class B and class B instantiates class C, then A instantiates D and D instantiates E.
A --> B ---> C
\
\--> D ---> E
This is all fine fine, until class E needs class C.
Then we need to re arrange everything and instantiate C higher up and pass it through class B and D down to both sides.
This is where DI comes into play.
We instead decide that A instantiates all classes
A --> B
--> C
--> D
--> E
So A is the owner of all classes, and he can then pass in any class to any class to meet whatever demand any class has.
This is what the Spring context does with the help of the #Autowire annotation. You declare for spring what class you want to be passed in the instantiated classes. Then Spring during startup, will instantiate all classes and then figure out what class should be fitted where (this is massive simplification). All classes will per default be instantiated as singletons (but this can be customised).
When spring instantiates you class it is called a spring managed bean. Spring manages the lifecycle of it. Not you, because you are not using new, the framework is.
During this process Spring does a number of checks and also instantiates in a specific order, configuration classes first, then #Bean annotated classes, and lastly #Component, #Service etc (overly simplifying this here), it will scan for what classes that should be instantiated, it will decide upon an order in which should be instantiated first, then which classes should be #Autowired into which classes. There are a number of help annotations that will assist Spring during this phase.
#Qualifier is one, you basically name a class, then you can tell spring where you want it #Autowired.
It's very useful if you have two singletons configured differently but they have the same name.
As you said, if you want different implementations you need to use #Qualifier("powerfulMapper") etc.
Lets suppose you have two different implementations one use #Qualifier("powerfulMapper") and the other is #Qualifier("notAPowerfulMapper").
Then while you autowire you also need to specify which one you need to inject like
#Autowired
#Qualifier("powerfulMapper")
private Mapper mapper;

Autowired Domain/Entity classes retains Old values

I have a mapper class for an incoming Event message.
Once the event message comes to the application, the mapper class sets the values in the entity object and saves it in the Database.
I have Autowired the entity object in my mapper class.
Whenever a new event comes in, the autowired entity object is still having the Old/previous values.
Is autowiring of Domain/Entity object possible in this case or I should go with 'New' keyword instead of Autowiring as Spring bean.
I see some posts about using #Configurable. I am not sure which is the best coding practice in this case?
#Service
public class LegacyEventMapper {
#Autowired
private LegacyEvent legacyEvent;
#Autowired
private LegacyEntity legacyEntity;
public void mapLegacyNotificationDetails(LegacyScheduleEvent body) throws Exception {
//Setting the values into the Entity object
Thanks
I have no idea why you actually want to #Autowire an #Entity and make it spring aware. This is wrong. You can do it, but it makes absolutely no sense.
What you actually want to do is create a new LegacyEntity (via the new LegacyEntity) and save that instance to DB.
What you have read via #Configurable is the other way around - you inject a spring bean/service into an Entity.
I think We can #Autowire an #Entity class. But then we need to mention in Entity class that it is of Request scope
#Entity
#Scope(scopeName=WebApplicationContext.SCOPE_REQUEST, proxyMode=ScopedProxyMode.TARGET_CLASS)
public class LegacyEntity {
I am not sure if using the new keyword is the better approach instead of autowiring an Entity class?

Is it possible to retrieve a Spring bean with prototype scope without using ApplicationContextAware

Using Spring 3.1. If I want to retrieve a bean with prototype scope (i.e. I want a different instance of the class each time), is it possible to retrieve the bean without having to use an ApplicationContextaware class?
This is how I do it at present
#Component
#Qualifier("MyService")
public class MyServiceImpl implements MyService {
#Override
public void doSomething() {
Blah blah = (Blah)ApplicationContextProvider.getContext().getBean("blah");
blah.setThing("thing");
blah.doSomething();
}
}
#Component("blah")
#Scope("prototype")
public class Blah {
....
}
where ApplicationContextProvider implements ApplicationContextAware.
Is it possible to do this with annotations or simple Spring configuration without having to use an ApplicationContextAware class?
Spring has some fairly sophosticated methods for achieving what you're after...
See the spring documentation: http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-factory-scopes-other-injection
Searching for spring proxy scope on google also threw up some results...
You don't really need a ApplicationContextAware. You just need a BeanFactory (ApplicationContextAware is just a convinient way to get it).
A bean with scope prototype just means that everytime ApplicationContext.getBean is called a new instance of the bean is created. If you try to inject a prototype bean in a singleton, your prototype bean will be injected once (and so is no more a prototype).
There is something called method injection that may help you if you really need it, but it is more complex than simply calling applicationContext.getBean().

how to implement Factory Pattern with Spring 3.0 Services

In my project I have an interface annotated with org.springframework.stereotype.Service tag.
I have two different implementation for this interface.
In my manage bean, I am injecting interface Service class and using its methods.
Now my requirement is, in run time I have to pick particular implementation (lets say based on login user group) so that respective logic can be invoked.
As per my understanding, we can achieve this using Factory pattern in java and achieve the same.
How can we implement this in SPRIng???
Besides suggested related topic above, there is a good thread on JavaRanch.
You can use
#Qualifier("myServiceImpl1") annotation together with #Autowired. In
that case this particular implementation of the interface will be
injected. You should also use the same name with your #Component,
#Service or #Repository annotations e.g.
#Service("myServiceImpl1")
public class MyServiceImpl1 implements MyService{}
public class Consumer{
#Autowired
#Qualifier("myServiceImpl1")
public MyService myServiceImpl1;
}
#Primary together with #Component, #Service or #Repository
annotations in your implementation class, in that case this
implementation will be injected by default.
If you mark a list of some interface type with #Autowired, all
available implementations of this interface will be injected.
#Autowired
public List<MyService> allAvailableImplementations;

Injecting a bean to use in Controllers throughout the application

I'm using spring mvc 3.1.x and jets3t.
I have a DataAccessObject that i instantiate as a Singleton bean..
I managed to get it working through extending the applicationcontextloader class and adding it to the web.xml
EDIT:
I changed my method, I tried inject and autowired but it's not suitable for my needs.
What I've done was to implement ApplicationContextAware and set it up as a bean, in the code I use it as follows:
ApplicationContext ctx = BannerApplicationContext.getApplicationContext();
BannerGenericDAO bdao = (BannerGenericDAO) ctx.getBean("dao");
I'm new to Spring and in general the servlet world..
Questions are:
what's the best way of doing this? Is this considered a "best-practice"?
How do you inject an object, keeping other method fields that are not supplied by autowiring?
How do you get an object to be used throughout the entire application?
Thanks!!
You could use annotations in your controller.
#Controller
public class MyController{
#Autowired // or #Inject, which is more JEEish (JSR330).
private SomeDao daoService;
}
Given "SomeDao" is the type of your singleton DAO, of course.

Resources