Spring的注解@Controller和@Service是否相同?

87

Spring注解@Controller@Service是否相同?

我知道@Controller可以用于URL映射和调用业务逻辑。

@Service用于注释包含业务逻辑的服务类。

我能否使用@Controller来替代@Service来注释服务类?

10个回答

142

不,它们互相之间非常不同。

两者都是@Component注释的不同专业化(实际上,它们是相同接口的两个不同实现),因此如果您在XML配置中声明它,则可以通过类路径扫描发现两者。

@Service注释用于您的服务层,并注释执行服务任务的类,通常您不使用它,但在许多情况下,您使用此注释来表示最佳实践。例如,您可以直接调用DAO类将对象持久化到数据库中,但这很糟糕。最好调用一个调用DAO的服务类。这是执行关注点分离模式的好方法。

@Controller注释是Spring MVC框架(用于实现Web应用程序的Spring Framework组件)中使用的注释。 @Controller注释指示特定类担任控制器角色。 @Controller注释充当带注释类的构造型,指示其角色。分派程序会扫描此类注释为映射方法,并检测@RequestMapping注释。

因此,在查看Spring MVC架构时,您有一个DispatcherServlet类(在XML配置中声明)表示一个前端控制器,该控制器将所有HTTP请求分派到适当的控制器类(由@Controller注释)。这个类通过其方法执行业务逻辑(并可以调用服务)。这些类(或其方法)通常还带有@RequestMapping注释,指定控制器及其方法处理哪个HTTP请求。

例如:

@Controller
@RequestMapping("/appointments")
public class AppointmentsController {

    private final AppointmentBook appointmentBook;

    @Autowired
    public AppointmentsController(AppointmentBook appointmentBook) {
        this.appointmentBook = appointmentBook;
    }

    @RequestMapping(method = RequestMethod.GET)
    public Map<String, Appointment> get() {
        return appointmentBook.getAppointmentsForToday();
    }

这个类是一个控制器。

这个类处理"/appointments"文件夹中所有的HTTP请求,特别是使用GET方法来处理所有针对文件夹"/appointments"的GET HTTP请求。

我希望现在您更清楚了。


3
非常清晰的解释。需要提醒一点,控制器类不必具有@RequestMapping注解,@RequestMapping也可以在方法级别上使用。 - timekeeper
2
我可以在单个类定义中混合它们吗?还是将它们实现为单独的类更好? - kensai

43

如果您查看@Controller@Service注释的定义,那么您会发现这些是@Component注释的特殊类型。

@Component
public @interface Service {
    ….
}

@Component
public @interface Controller {
    …
}

那么它们之间有什么区别?

@Controller

@Controller注解指示特定的类充当控制器角色。@Controller注释充当带注释类的原型,指示其作用。

@Controller 有什么特别之处?

您不能将此注释与其他任何注释交换,例如@Service@Repository,即使它们看起来相同。 调度程序会扫描带有@Controller注解的类,并在其中检测@RequestMapping注解。你只能在带有@Controller注解的类上使用@RequestMapping


@Service

@Service包含业务逻辑并调用存储库层中的方法。

@Service 有什么特别之处?

除了用于指示它保存业务逻辑这个事实之外,该注释没有任何显著的特点,但是谁知道,Spring可能会在未来添加一些额外的异常。

相关回答:Spring中 @Component、@Repository 和 @Service 注释之间有什么区别?


7
不,@Controller并不等同于@Service,尽管它们都是@Component的专业化,并且都可以被类路径扫描发现。 @Service注释用于您的服务层,而@Controller用于Spring MVC控制器在您的表示层中。 @Controller通常会有一个URL映射,并通过Web请求触发。

5
@Service vs @Controller
@Service:被注释的类是“业务服务外观”(在核心J2EE模式中),或类似的东西。
@Controller:指示被注释的类是“控制器”(例如,Web控制器)。
----------在主要构造类型中找到有用的注释 http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/stereotype/Component.html @interface Component
  @Target(value=TYPE)
     @Retention(value=RUNTIME)
     @Documented
    public @interface Component

该注释表示被注释的类是一个组件。当使用基于注释的配置和类路径扫描时,这样的类被视为自动检测的候选对象。

其他类级别的注释也可以被视为识别组件的标识,通常是一种特殊类型的组件,例如@Repository注释或AspectJ的@Aspect注释。

@interface Controller

@Target(value=TYPE)
 @Retention(value=RUNTIME)
 @Documented
 @Component
public @interface Controller

该注解表示一个被注释的类是“控制器”(例如,Web控制器)。

此注解是@Component的特化版本,允许通过类路径扫描自动检测实现类。通常与基于RequestMapping注解的注释处理程序方法结合使用。

@interface Service

@Target(value=TYPE)
 @Retention(value=RUNTIME)
 @Documented
 @Component
public @interface Service

这个注解表示一个被注解的类是一个"Service",最初由领域驱动设计(Evans, 2003)定义为“作为接口提供的操作,在模型中独立存在,没有封装状态。”

也可以表示一个类是一个"Business Service Facade"(在核心J2EE模式意义上),或者其他类似的含义。这个注解是一个通用的模式化标志,每个团队可以根据需要缩小它们的语义并使用。

这个注解作为@Component注解的特殊化,允许通过类路径扫描自动检测实现类。

@interface Repository

@Target(value=TYPE)
 @Retention(value=RUNTIME)
 @Documented
 @Component
public @interface Repository

该注解表示一个带有注释的类是"存储库"(Repository),最初由领域驱动设计(Evans, 2003)定义为“一种封装存储、检索和搜索行为以模拟对象集合的机制”。 实现传统J2EE模式(如“数据访问对象”)的团队也可以将此模式应用于DAO类,但在这样做之前,应注意了解数据访问对象和DDD风格存储库之间的区别。该注解是一个通用的模式,各个团队可以根据需要缩小其语义并使用。
因此,使用PersistenceExceptionTranslationPostProcessor结合使用时,具有此注释的类可以进行Spring DataAccessException翻译。对于工具、方面等的目的,已经明确了带注释的类在整个应用程序架构中的角色。
从Spring 2.5开始,此注解还作为@Component的专业化,允许通过类路径扫描自动检测实现类。

1
你可以将一个@service声明为@Controller
不能@Controller声明为@Service@Service 这很普通。你只是将类声明为组件。 @Controller 它比组件更特殊。 调度程序将在此处搜索@RequestMapping。 因此,使用@ Controller注释的类将通过声明调用API的URL来获得额外的授权。

1

我已经在这里回答了类似的问题 这是链接

不,它们两个是不同的。

@Service注解有其他用途,而@Controller注解则有其他用途。 实际上,Spring框架中的@Component、@Service、@Repository和@Controller注解都用于使用类路径扫描自动检测bean,但这并不意味着所有功能都相同。 @Service:表示被注释的类是业务层中的服务组件。

@Controller:被注释的类表示它是控制器组件,主要用于表示层。


1
  • 控制器将处理不同视图之间的导航。请求映射将在控制器的帮助下处理。
  • 服务直接与存储库交互,通常在此层执行业务逻辑。您可以在服务层添加、删除、移除等操作。

0

不行,它们是不同的。例如,当应用程序部署时,您的控制器映射将会出现问题。

无论如何,为什么要这样做呢?控制器不是服务,反之亦然。


0

来自Spring In Action

正如您所看到的,这个类被注释为@Controller。单独使用@Controller并没有太多作用。它的主要目的是将此类标识为组件以进行组件扫描。因为HomeController被注释为@Controller,所以Spring的组件扫描会自动发现它,并在Spring应用程序上下文中创建HomeController实例作为bean。

事实上,还有一些其他注释(包括@Component、@Service和@Repository)与@Controller类似。您可以使用任何这些其他注释之一有效地注释HomeController,并且它仍然可以正常工作。但是,选择@Controller更能描述此组件在应用程序中的角色。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接