Spring Boot Annotations
@SpringBootApplication -> @Configuration + @EnableAutoConfiguration + @ComponentScan
@Component -> Marks a Java class as a bean so that component scanning mechanism of spring can pick it up and pull it into the application component.
@EnableAutoConfiguration -> Spring Boot auto-configuration automatically configure a Spring application based on the dependencies present on the classpath. Spring Boot detects classes in the classpath and auto-configuration mechanism will ensure to create and wires necessary beans for us. This is one of the most powerful feature of the Spring Boot and most of the work happens silently in the background.
@Service -> It is similar to component, but it is good to use with service classes. It specifies the actual intent of the class.
@Repository -> Used with Dao layer classes, makes sure that unchecked exceptions thrown eligible to be translated into spring data access exception.
@Controller -> Marks the class as spring MVC controller.
@RestController -> @Controller + @Responsebody. It eliminates the need to annotate every request handling method of that class with @Responsebody. It signifies a REST API that will return a JSON response.
@Configuration -> Marks that the class contains one or more beans defined inside. This is going to be your configuration class. Example some initializations you have to do, add a interceptor, etc. If any configuration we need to do in a class then we should use this annotation.
@Bean -> tells that a method produces a bean to be managed by the Spring container.
@Autowire -> It is used for dependency injection. The @Autowired annotation provides more fine-grained control over where and how autowiring should be accomplished. It's default byType in spring boot. XML attribute autowire is default as no.
What is a Bean?
A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container.
@Autowired vs @Bean
When we mark a class with @Component then we can use @Autowire to get the instance of the class.
Sometimes we use 3rd part code and we can't modify the source code to add @Component then in that case we can use @Bean to create instance of that class and register with spring IOC and when I need I can have with @Autowire annotation.
@Qualifier -> This is used to resolve the autowiring conflict, when there are multiple beans of same type.
@Component("fooFormatter")
public class FooFormatter implements Formatter {
public String format() {
return "foo";
}
}
@Component("barFormatter")
public class BarFormatter implements Formatter {
public String format() {
return "bar";
}
}
public class FooService {
@Autowired
@Qualifier("fooFormatter")
private Formatter formatter;
}
Autowiring Types
No. | Mode | Description |
---|---|---|
1) | no | It is the default autowiring mode. It means no autowiring bydefault. |
2) | byName | The byName mode injects the object dependency according to name of the bean. In such case, property name and bean name must be same. It internally calls setter method. |
3) | byType | The byType mode injects the object dependency according to type. So property name and bean name can be different. It internally calls setter method. |
4) | constructor | The constructor mode injects the dependency by calling the constructor of the class. It calls the constructor having large number of parameters. |
5) | autodetect | It is deprecated since Spring 3. |
Spring Bean Scopes
The latest version of the Spring framework defines 6 types of scopes:
- singleton
- prototype
- request
- session
- application
- websocket
The last four scopes mentioned, request, session, application and websocket, are only available in a web-aware application.
Singleton
When we define a bean with the singleton scope, the container creates a single instance of that bean; all requests for that bean name will return the same object, which is cached. Any modifications to the object will be reflected in all references to the bean. This scope is the default value if no other scope is specified.
@Bean
@Scope("singleton")
public Person personSingleton() {
return new Person();
}
Prototype
A bean with the prototype scope will return a different instance every time it is requested from the container. It is defined by setting the value prototype to the @Scope annotation in the bean definition.
@Bean
@Scope("prototype")
public Person personPrototype() {
return new Person();
}
Want to exclude some dependencies mentioned in the pom.xml?
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
Conditional Beans
@Conditional Annotation
Before we get into details of how Spring Boot auto-configuration works, let’s take a broader look at the @Conditional
annotation. This annotation is the base and most annotations used by the Spring Boot auto-configuration are extensions of this annotation. The @Conditional
annotation introduced in Spring 4 is an improvement to the Spring profile feature. It adds flexibility to the developer to register beans based on several conditions like:
- A type-level annotation on any class directly or indirectly annotated with @Component, including @Configuration classes.
- As a meta-annotation, for the purpose of building custom stereotype annotations.
- Method-level annotation on any @Bean method.
Let’s pick an example, where we need to implement a tax rate service based on user country. Let’s examine how our code base looks like:
public interface TaxCalculationService{
Double getTaxRate();
}
This is our TaxCalculationService implementation detail
public class USTaxCalculationService implements TaxCalculationService{
@Override
public Double getTaxRate(){
// Tax rate for US
}
}
public class CATaxCalculationService implements TaxCalculationService{
@Override
public Double getTaxRate(){
// Tax rate for Canada
}
}
Let’s carry out the condition based on the user country:
public class USTaxCalculationTypeCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
return Locale.getDefault().equals(Locale.US);
}
}
We can have an identical implementation for the Canadian tax service. Let’s look at how to apply these conditions in our configurations to load beans conditionally:
@Configuration
public class AppConfig {
@Bean
@Conditional(USTaxCalculationTypeCondition.class)
public TaxCalculationService usTaxCalculationService() {
return new USTaxCalculationService();
}
@Bean
@Conditional(CATaxCalculationTypeCondition.class)
public TaxCalculationService caTaxCalculationService() {
return new CATaxCalculationService();
}
}
If we run our application, Spring will ensure to load the correct bean based on country (Locale in our example). Now we have the key knowledge of The @Conditional
annotation,let’s learn how Spring Boot use this feature for the auto-configuration.
Comments
Post a Comment