Exclude #SpringBootApplication from component scanning - spring-boot

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

Related

How to tell SpringBootTest to load all required classes without explicitly having to specify them

As far as I understand, you have two options with SpringBootTests:
Load the whole application
Load only what you need by specifying the classes explicitly
However, if you do 2., depending on how large the part of the application is you want to test, you'll end up with a long list of classes
#pringBootTest
#ContextConfiguration(classes = {
A.class, B.class, C.class, D.class, E.class,
F.class, G.class, H.class, I.class, J.class,
K.class, L.class, M.class, N.class, O.class,
P.class, Q.class, R.class
})
And whenever parts of what you want to test change, you have to figure out what beans are missing and manually add them to the list.
Is there any way to tell Spring if you want to test A.class to automatically detect and load the dependents automatically?
B.class, C.class, D.class, E.class, F.class, G.class, H.class, I.class, J.class, K.class, L.class, M.class, N.class, O.class, P.class
Just omit the #ContextConfiguration completely. #SpringBootTest will then create the whole application context.
There is a way for reducing manual work. First, need to group all the beans need to test your class in a configuration class annotated with #Configuration .
#Configuration
public class ConfigClass{
//define all necessary Beans here required for testing
}
Then need to give the class annotated with #Configuration as a value to classes attribute
#ContextConfiguration(classes={ConfigClass.class})

How does spring boot #Value("${somevalue}") annotation work?

I have some #Value annotation in spring-boot project. To Simplify, I have few classes: a restcontroller, service (annotated with #Service) and a pojo.
In each of these classes, I declared a variable as below:
#Value("${somevalue}")
private String somevalueVariable
In the controller class, the value is getting populated as defined in the application.properties. So no problem here.
In the service class, the value is showing up as null. This is my issue, how should i fix it to get the value from the application.properties
In the pojo, the value is showing up as null, I am thinking this is expected behaviour as spring does not manage this class.
Try this:
import org.springframework.beans.factory.annotation.Value;
#Value("#{${somevalue}}")
private String somevalueVariable
ideally service class should have #Service anotation over it, either you missed that or this class is not scanned by spring context, so please add ComponentScan anotation for service class package over main class to scan classes uner this package -
#SpringBootApplication
#ComponentScan({"com.in28minutes.springboot"})
public class Application
It uses Spring Expression Language (SpEL):
https://docs.spring.io/spring-integration/docs/5.3.0.RELEASE/reference/html/spel.html
Also there is 2 #Value : org.springframework.beans.factory.annotation.Value and lombok.Value;
Make sure you are using the right one.
To get value from property try this:
#Value("${systemValue}")
private String systemValue;
For more information I find this useful:
https://www.baeldung.com/spring-value-annotation

behaviour difference between #Configuration and #Component

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.

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;
}

#Configuration within #Controller or #Configuration

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.

Resources