Spring @Bean vs @Service注解区别
今天跟同事讨论了一下在spring boot中,是使用@configuration和@bean的组合来创建bean还是直接使用 @service等注解放在类上的方式。笔者倾向于使用第一种,即@configuration和@bean的组合。
先来看一个例子,目标是创建searchservice的一个bean。
直接使用@service的方式:
// searchservice.java package li.koly.search; import java.util.list; public interface searchservice { list<object> search(string q); } // elasticsearchserviceimpl.java package li.koly.search; import org.springframework.stereotype.service; import java.util.arrays; import java.util.list; @servicecomponent public class elasticsearchserviceimpl implements searchservice { @override public list<object> search(string q) { return arrays.aslist("hello", q); } } // application.java package 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 @restcontroller public 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); } }
启动application,浏览器访问: http://localhost:8081/search?q=koly ,页面显示:["hello","koly"]
使用@configuration和@bean的方式:
// elasticsearchserviceimpl.java package 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.java package li.koly.search; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; @configuration public class appconfig { @bean public searchservice searchservice() { return new elasticsearchserviceimpl(); } }
相比直接使用@service的代码,多了一个appconfig类,移除了放在elasticsearchserviceimpl上面的@service注解。一眼看去,代码和类还多了。那么使用后者的好处是什么呢?
笔者认为,好处有:
关注点分离
使用@configuration和@bean的方式,bean的创建全部放到了一个地方,接口及其实现完全跟bean创建没有了关系。
如果bean的创建需要改动,那么只需要查看并修改对应的configuration类就行,并不需要去到对应的java bean进行改动。比如可能有时候bean创建需要同@scope或者@profile配合,此时只需要修改configuration类就行了。
单一职责
@service注解本身就承担了两个职责:
一是bean的创建;
二是将一个类标识为一个服务。
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."
上面是spring对于@service注解的说明。也就是说@service实际上表示了ddd中的无状态的,独立的,以接口的形式提供的一个操作。
而采用@bean和@configuration配合的方式,bean的创建交给了单独的类,而service的标识交给了java中的interface以及类的名字。这点在spring data也有所体现,比如repository就是通过名字来标识,如crudrepository。因此service也通过名字来体现。具体层次定义,通过名字而不依赖spring提供的注解,便于根据项目提供更多的层次,比如mapper层,validator层等。
另为,本身bean和service就是两个维度的概念。一个关于具体实现,另一个关于ddd中的概念。
更灵活
使用@bean的方式,能够创建库里面的类的实例。如果使用@service的方式,没办法在库里面对应的类上添加@service注解。
least knowledge(最小知识原则)
最小知识原则的意思是:
完成功能需要的技术或者知识越少越好,这样才能保证项目简单,同时降低项目的学习难度。
由于使用@service无法创建类库中的类的实例,因此在遇到类似需求时,不得不使用@configuration和@bean的形式。此时,整个项目中就同时存在@service,@configuration和@bean等注解,而这些注解所做的事情都是一样的,即bean的创建。
使用@service,很有可能出现@service,@component,@configuration和@bean同时存在的情况。
而使用@configuration和@bean则完全可以不使用@service和@component,符合最小知识原则。
最后,顺便说一句,之前spring的bean创建是在xml里面,后面使用了java做配置。不使用xml的主要原因是xml不够简洁,且没有编译时检查等功能,而不是说需要将bean的创建分散到各个类里。
综上,笔者更倾向与使用@configuration和@bean的方式。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
Spring @Bean vs @Service注解区别
-
Spring启动后获取所有拥有特定注解的Bean实例代码
-
Spring框架中 @Autowired 和 @Resource 注解的区别
-
Spring 中 @Service 和 @Resource 注解的区别
-
spring IOC容器 Bean管理(基于注解方式)
-
Spring启动后获取所有拥有特定注解的Bean实例代码
-
Spring框架中 @Autowired 和 @Resource 注解的区别
-
荐 Spring-boot-study02-spring.xml配置文件注入组件和@Bean注解注入组件差别
-
Spring中@Component与@Bean的区别
-
@Resource 与 @Service注解的区别