Today I discussed with my colleagues whether to use the combination of @Configuration and @Bean to create a bean or directly use @Service and other annotations to place it on the class. The author tends to use the first type, namely the combination of @Configuration and @Bean.
Let’s first look at an example, the goal is to create a Bean of SearchService.
Directly use @Service:
// SearchService.javapackage li.koly.search;import java.util.List;public interface SearchService { List<Object> search(String q);}// ElasticSearchServiceImpl.javapackage li.koly.search;import org.springframework.stereotype.Service;import java.util.Arrays;import java.util.List;@ServiceComponentpublic class ElasticSearchServiceImpl implements SearchService { @Override public List<Object> search(String q) { return Arrays.asList("hello", q); }}// Application.javapackage li.koly.search;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import java.util.List;@SpringBootApplication@RestControllerpublic class Application { @Autowired private SearchService searchService; @GetMapping("/search") public List<Object> hello(String q) { return searchService.search(q); } public static void main(String[] args) { SpringApplication.run(Application.class, args); }}Start Application, browser access: http://localhost:8081/search?q=koly, page display: ["hello","koly"]
How to use @Configuration and @Bean:
// ElasticSearchServiceImpl.javapackage li.koly.search;import java.util.Arrays;import java.util.List;public class ElasticSearchServiceImpl implements SearchService { @Override public List<Object> search(String q) { return Arrays.asList("hello", q); }}// AppConfig.javapackage li.koly.search;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class AppConfig { @Bean public SearchService searchService() { return new ElasticSearchServiceImpl(); }}Compared to the code that directly uses @Service, there is an AppConfig class, and the @Service annotation placed on ElasticSearchServiceImpl is removed. At first glance, there are more codes and classes. So what are the benefits of using the latter?
The author believes that the benefits are:
Separation of concerns
Using @Configuration and @Bean, the creation of beans is placed in one place, and the interface and its implementation have nothing to do with the creation of beans.
If the creation of the bean needs to be changed, then you only need to view and modify the corresponding Configuration class, and you do not need to go to the corresponding Java Bean for changes. For example, sometimes the creation of beans requires cooperation with @Scope or @Profile, and you only need to modify the Configuration class at this time.
Single Responsibility
The @service annotation itself assumes two responsibilities:
One is the creation of beans;
The second is to identify a class as a service.
Indicates that an annotated class is a "Service", originally defined by Domain-Driven
Design (Evans, 2003) as "an operation offered as an interface that stands alone in the model, with no encapsulated state."
The above is Spring's explanation of @Service annotation. That is to say, @Service actually represents a stateless, independent, operation provided in DDD.
Using the method of @Bean and @Configuration, the creation of the bean is handed over to a separate class, and the Service identity is handed over to the Interface and the class name in Java. This is also reflected in Spring Data. For example, Repository is identified by name, such as CrudRepository. Therefore, Service is also reflected by its name. Specific hierarchy definition, through the name, without relying on the annotations provided by Spring, is convenient to provide more hierarchies according to the project, such as the Mapper layer, Validator layer, etc.
In addition, Bean and Service are two dimensions. One is about concrete implementation and the other is about concepts in DDD.
More flexible
Using @Bean, you can create instances of classes in the library. If you use @Service, you cannot add @Service annotation to the corresponding class in the library.
least knowledge (minimum knowledge principle)
The minimum knowledge principle means:
The less technology or knowledge required to complete the function, the better, so as to ensure that the project is simple and reduce the difficulty of learning the project.
Since using @Service cannot create an instance of a class in the class library, when encountering similar requirements, you have to use the form of @Configuration and @Bean. At this time, annotations such as @Service, @Configuration and @Bean exist in the entire project at the same time, and the things these annotations do are the same, that is, the creation of the bean.
With @Service, it is very likely that @Service, @Component, @Configuration and @Bean will exist simultaneously.
When using @Configuration and @Bean, you can completely ignore @Service and @Component, which complies with the principle of minimum knowledge.
Finally, by the way, Spring's bean was created in XML before, and Java was used for configuration later. The main reason for not using xml is that xml is not concise enough and does not have any functions such as compile-time checking, rather than scattering the creation of beans into various classes.
In summary, the author prefers to use @Configuration and @Bean.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.