how to implement Factory Pattern with Spring 3.0 Services - spring

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;

Related

Spring Boot - Override bean from controller

I have two controllers (ControllerA and ControllerB)
Both controllers call to a service (MyService).
MyService calls to an interface called MyRepository which has two implementations (FirstRepository and SecondRepository).
How is possible to use FirstRepository when the service (MyService) is called from ControllerA and use SecondRepository when the call comes from ControllerB?
This way I can reuse MyService and which repository is used comes from Spring Configuration.
I can see two possible solutions here.
1. In you MyService class autowire both implementations with #Qualifier annotation (you can also autowire List.
Then MyService method would have a parameter saying which MyRepository implementation should be called. I would not recommend this solution.
2. Define two implementations of MyService (FirstService, SecondService). Then FirstService would autowire FirstRepository and SecondService would autowire SecondRepository (use #Qualifier annotation again. Now you can easily inject FirstService to ControllerA and SecondService to ControllerB.
But first I would think about architecture. Maybe you don't need separate controllers?
Have you checked #Primary or #Resource or #Qualifier annotations? Based on your requirement you can choose out of them.
Something similar has been discussed here.
I ended up creating two controllers and defining two #Configuration classes, one for each #Controller.
And using the #Qualifier annotations defined two sets of beans, and then in each controller let Spring know which #Qualified bean I want injected.
#RestController
#RequestMapping("/v1/inapp/purchases")
class AController(
#Qualifier("appStore") private val redeemPurchaseService: RedeemPurchaseService
) : RedeemPurchaseApiDocumentation { // More code }
And the other controller
#RestController
#RequestMapping("/v1/inapp/purchases")
class GPlayRedeemPurchaseController(
#Qualifier("gplay") private val redeemPurchaseService: RedeemPurchaseService
) : RedeemPurchaseApiDocumentation { // More code }
And two #Configuration files, one per controller.

Can impl bean in spring have more public methods than Interface?

if there is an interface in spring with 1 abstract public method and an implementation of this interface with 2 public methods (1 is overide and second public method is extra). If we autowire the interface we are not able to use the second public method in impl. Is this a correct behavior? In maven build it does say its using and autowiring IMPL bean but not able to find the second extra public method.
It's more of a Java question rather than a Spring one. There are a few things going on here:
Yes, an implementation can have more methods than the interface it's implementing.
Since you cannot initialize an interface, as in Spring case, it can only autowire an implementation of the interface to your bean.
Let's look at the following example:
You have an interface SomeInterface with methods methodA, and it's implementation SomeInterfaceImpl with methodA and methodB.
If you autowire a bean by its interface:
#Autowired private SomeInterface someInterface;
then you can only access methodA (without explicitly casting it to SomeInterfaceImpl, obviously), although what you have autowired is SomeInterfaceImpl and has methodB implemented.
If you autowire its impltementation:
#Autowired private SomeInterfaceImpl someInterface;
then you'll be able to access both methodA and methodB. HTH.

Can we write #Component or any other annotations on DTO classes

I am working with Spring Restful and Hibernate. To remove the redundancy in code I want to avoid the object creation of DTO in each and every methods and want to declare it with #Component annotation, I want to know is there any specific rules for DTOs as we have some guidelines for POJO and JavaBeans.
Check Spring Doc
https://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-stereotype-annotations
7.10.1 #Component and further stereotype annotations
Spring provides further stereotype annotations: #Component, #Service, and #Controller. #Component is a generic stereotype for any Spring-managed component. #Repository, #Service, and #Controller are specializations of #Component for more specific use cases, for example, in the persistence, service, and presentation layers, respectively. Therefore, you can annotate your component classes with #Component, but by annotating them with #Repository, #Service, or #Controller instead, your classes are more properly suited for processing by tools or associating with aspects. For example, these stereotype annotations make ideal targets for pointcuts. It is also possible that #Repository, #Service, and #Controller may carry additional semantics in future releases of the Spring Framework. Thus, if you are choosing between using #Component or #Service for your service layer, #Service is clearly the better choice. Similarly, as stated above, #Repository is already supported as a marker for automatic exception translation in your persistence layer.
You can create a static method which returns the Object of your DTO class and you can call this method from anywhere to get the instance of that class like this..
private DTOObject dtoObject;
public static DTOObject getInstance() {
if(dtoObject == null) {
dtoObject = new DTOObject();
}
return dtoOject;
}

Does Spring #transaction work on a concrete method of abstract class

From spring reference doc
Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the #Transactional annotation, as opposed to annotating interfaces. You certainly can place the #Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java
annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad.
Though it only talks about interfaces, abstract classes are considered as non-concrete as well.
So if i have an abstract class
public abstract class BaseService{
//here is a concrete method
#Transactional
public void updateData{
//do stuff using dao layer
}
and a concrete class which extends the class
public class SpecialService extends BaseService{
//body of class
}
Now if i call specialService.updateData() from my controller class will it be transactional?
Granting that you have actually configured Spring transaction management correctly, using #Transactional on an abstract superclass will work, since #Transactional is itself annotated with #Inherited and from it's Javadoc we have:
Indicates that an annotation type is automatically inherited. If an
Inherited meta-annotation is present on an annotation type
declaration, and the user queries the annotation type on a class
declaration, and the class declaration has no annotation for this
type, then the class's superclass will automatically be queried for
the annotation type. This process will be repeated until an annotation
for this type is found, or the top of the class hierarchy (Object) is
reached. If no superclass has an annotation for this type, then the
query will indicate that the class in question has no such annotation.
Note that this meta-annotation type has no effect if the annotated
type is used to annotate anything other than a class. Note also that
this meta-annotation only causes annotations to be inherited from
superclasses; annotations on implemented interfaces have no effect.
To actually see that #Transactional is annotated with #Inherited check out it's Javadoc

Spring interface loading

i'm wondering if spring loads an interface when declared as an #autowired attribute of an implementation class without having annotated the interface as a #component .
let me describe my problem a bit more :
i have both an interface and its implementation class have the same name but they reside in different packages . i annotated the implementation as #Component("myImplementation") .
but i end up having an exception that says :
conflicts with existing, non-compatible bean definition of same name and class
i'm thinking of excluding interfaces from <context:component-scan , what do you think ?
PS : my interface isn't #Component annotated , the application runs just fine on developpement environement , i only get the error after Proguard obfuscation
Your proguard.conf should be contain:
## ... preserve class annontation (Java EE 1.6 DI)
# Spring3
#-keep #org.springframework.stereotype.Service class *
-keep #org.springframework.stereotype.Controller class *
#-keep #org.springframework.stereotype.Component class *
#-keep #org.springframework.stereotype.Repository class *
proguard forums has more detailed answers.
Annotating your implementation with #Component and not annotating your interface is usually the right way to set things up. Spring's auto-wiring will look for a managed bean of a matching type, and your implementation will match for a field typed to the interface. If your interface is not annotated with #Component, or any Spring stereotype annotation, it should not be loaded into the context during a component scan. So, you should not have a problem if the interface and implementation have the same class name.
Are you sure you've tried not annotating the interface? Are you sure you don't have some other class somewhere else in your project that also has the same name as the interface and its implementation?
Well I think moving interfaces in different package would work because you would create object reference of interface and respective implementation beans would be auto wired to those object references. But you should follow naming conventions. There would be problem when differentiating interfaces and implementation classes as names are same. Follow standards like
interface SomeInterface {
//....
}
for implementation class of SomeInterface
class SomeInterfaceImpl implements SomeInterface {
// implementation....
}

Resources