Spring @Bean vs @Service注解区别

 更新时间:2017年12月13日 09:36:19   作者:Mr_Hospital  
本篇文章主要介绍了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的方式。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 解决Intellij IDEA 使用Spring-boot-devTools无效的问题

    解决Intellij IDEA 使用Spring-boot-devTools无效的问题

    下面小编就为大家带来一篇解决Intellij IDEA 使用Spring-boot-devTools无效的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • Java毕业设计实战之在线蛋糕销售商城的实现

    Java毕业设计实战之在线蛋糕销售商城的实现

    这是一个使用了java+JSP+Springboot+maven+mysql+ThymeLeaf+FTP开发的在线蛋糕销售商城,是一个毕业设计的实战练习,具有线上蛋糕商城该有的所有功能,感兴趣的朋友快来看看吧
    2022-01-01
  • java基于quasar实现协程池的方法示例

    java基于quasar实现协程池的方法示例

    本文主要介绍了java基于quasar实现协程池的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧<BR>
    2022-06-06
  • 浅谈Java线程池的7大核心参数

    浅谈Java线程池的7大核心参数

    本篇文章基于正在看这篇文章的你已经具备了基本的Java并发的相关知识.如果对于Java并发编程一无所知的话,请先看看Java并发编程的一些前导基础知识,文中有非常详细的图文示例及代码,,需要的朋友可以参考下
    2021-05-05
  • java“与”符号写法与用法

    java“与”符号写法与用法

    在本篇文章里小编给大家整理的是关于java“与”符号写法与用法,对此有需要的朋友们可以学习下。
    2020-02-02
  • spring配置文件加密方法示例

    spring配置文件加密方法示例

    这篇文章主要介绍了spring配置文件加密方法示例,简单介绍了什么是配置文件,然后分享了在实际生产环境中,对配置文件不允许出现明文用户名及密码等信息需求的Java实现代码,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • SpringBoot如何接收前端传来的json数据

    SpringBoot如何接收前端传来的json数据

    这篇文章主要介绍了SpringBoot如何接收前端传来的json数据问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • Java中Scanner的用法示例小结

    Java中Scanner的用法示例小结

    有时候我们在编写代码的时候可能会使用输入和输出,那Java也有自己的输入和输出,今天我们来探究一下,对Java Scanner用法相关知识感兴趣的朋友一起看看吧
    2025-04-04
  • Spring Bean生命周期之Bean的注册详解

    Spring Bean生命周期之Bean的注册详解

    这篇文章主要为大家详细介绍了Spring Bean生命周期之Bean的注册,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • Java将字符串转化为数组的两种方法

    Java将字符串转化为数组的两种方法

    Java中的String类是一种特殊的字符串,它可以被用于处理字符串,Java中的String类也可以将字符串转换为数组,下面这篇文章主要给大家介绍了关于Java将字符串转化为数组的两种方法,需要的朋友可以参考下
    2023-05-05

最新评论