Is there any difference between behaviour of #Configuration and #Componentannotation in Spring framework?
Is there any situation when changing #Configuration to #Component will change program's behaviour?
I did a few experiments and from what I see so far, they always work the same.
Notice that I'm interested specifically in the difference of behaviour - I already know that the two annotations are usually used in different situations.
Your #Configuration class can be annotated also with #ComponentScan
we use the #ComponentScan annotation along with #Configuration annotation to specify the packages that we want to be scanned
If you change to #Component it won't work as expected
See also difference between #Configuration and #Component
#Configuration is also a #Component but a #Component cannot act like a #Cofinguration
While they both make annotated classes beans, they serve different purposes.
Treat a class with #Configuration as a part of your application context where you define beans. Usually, you have #Bean definitions in your #Configuration class.
#Component annotation, on the other hand, means that your class IS a bean itself and that it.
So, for example you need a bean MyService.
You can define it in two ways:
#Configuration
public class MyAppConfig {
#Bean
public MyService myService(){
return new MyServiceImpl();
}
}
or just
#Component
public class MyServiceImpl {
...
}
So, when you use your #Configuration as a configuration, adding things specific to it (#ComponentScan, #Bean, ...) it would have a different behaviour and it won't work with just #Component instead.
Related
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.
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;
}
I have two classes marked as #SpringBootApplication under one directory:
#SpringBootApplication
public class FirstSpringBootApplication
and
#SpringBootApplication
public class SecondSpringBootApplication
#SpringBootApplication annotation contains #ComponentScan annotation and #EnableAutoConfiguration annotation. So, each of two of these classes will consider another as #Configuration bean. How to exclude FirstSpringBoodApplication from component scanning by SecondSpringBootApplication without using profiles?
The annotate class with below annotations will work similarly as #SpringBootApplication. It also does the same, and the excludeFilter is important, which is used to specify which class not to include while scanning.
#EnableAutoConfiguration
#ComponentScan(excludeFilters={#Filter(type=CUSTOM, classes={TypeExcludeFilter.class})})
In case you need to define two or more excludeFilters criteria, you have to use the array.
For instances in this section of code I want to exclude all the classes in the org.xxx.yyy package and another specific class, MyClassToExclude
I have seen the AutoConfiguration classes, that defines #Configuration within an #Configuration and these are all static. Why they should be static? Is it a better way.
What is the difference between the #Configuration defined within #Component class and stand-alone #Configuration class?
Take a look at the definition of WebMvcAutoConfigurationAdapter in the source code for WebMvcAutoConfiguration to find your answer:
// Defined as a nested config to ensure WebMvcConfigurerAdapter is not read when not
// on the classpath
#Configuration
#Import(EnableWebMvcConfiguration.class)
#EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
public static class WebMvcAutoConfigurationAdapter extends WebMvcConfigurerAdapter {
...
}
The auto-configuration classes are defined as nested static classes to prevent Spring's component-scanning from picking them up automatically when the proper annotation has not been used. So a good rule of thumb would be to define your configuration classes as stand-alone classes if you expect them to be used every time, or as nested static classes if you'd like to isolate them from classpath scanning.
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;