当前位置: 移动技术网 > IT编程>开发语言>Java > Spring @Bean vs @Service注解区别

Spring @Bean vs @Service注解区别

2019年07月19日  | 移动技术网IT编程  | 我要评论

今天跟同事讨论了一下在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的方式。

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网