@controller注解_Spring中 @Controller @Service @Repository 有什么区别?

32df0476317f8fa5509a06d8ee331677.png

经常使用Spring的注解@Controller @Service @Repository @Component,却不知道他们之间有什么区别,一起来看看。

一、源码

  • @Component
public @interface Component {
    String value() default "";
}
  • @Repository
@Component
public @interface Repository {
    @AliasFor(annotation = Component.class)
    String value() default "";
}
  • @Service
@Component
public @interface Service {
    @AliasFor(annotation = Component.class)
    String value() default "";
}
  • @Controller
@Component
public @interface Controller {
    @AliasFor(annotation = Component.class)
    String value() default "";
}

以上代码省略了一些细节,看了以上代码你就会发现无论是@Controller@Service还是@Repository全部都被@Component注解了。在Spring源码中,注解会一级一级向上递归搜索,搜索所有的注解信息,即被以上注解注解的类在Spring看来都会包含@Component注解。 而@Component在原文表述为:

/**
 * Indicates that an annotated class is a "component".
 * Such classes are considered as candidates for auto-detection
 * when using annotation-based configuration and classpath scanning.
 * 表明被注释的类是一个“组件”。
 * 当使用基于注释的配置或类路径扫描时,这些类被视为自动检测的候选类。
 *
 * <p>Other class-level annotations may be considered as identifying
 * a component as well, typically a special kind of component:
 * e.g. the {@link Repository @Repository} annotation or AspectJ's
 * {@link org.aspectj.lang.annotation.Aspect @Aspect} annotation.
 *
 * @author Mark Fisher
 * @since 2.5
 * @see Repository
 * @see Service
 * @see Controller
 * @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner
 */

综上所述,本质上@Controller@Service@Repository@Component本质都是@Component,即Spring容器中的一个组件。

二、如果都相同,那为什么不直接都用@Component就好了?

相信做过java web的都知道MVC的概念,都知道一个基于MVC的java web项目一般可以简单划分为:Controller、Service、Dao、Util等,如果给Controller、Service、Dao都使用@Component那么不利于逻辑分层,添加这三个注解的主要目的就是为了逻辑分层,无论开发者给Controller命名为XxxYyyZzz还是AaaBbbCcc,只要注解有@Controller,那么可以理解为祖传代码的意思就是这一块就是Controller层。

三、这几个注解真的没区别吗?

如下代码:

import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
​
@Component
public class DiffController {
​
    @RequestMapping("hello")
    @ResponseBody
    public Object hello(){
        return "hello world!";
    }
}

在网页中访问会404。

0ae05a0eb9f938062a4d59d9c38e8d9a.png
404

而当我使用@Controller进行注解时便会出现如下结果:

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
​
@Controller
public class DiffController {
​
    @RequestMapping("hello")
    @ResponseBody
    public Object hello(){
        return "hello world!";
    }
}

7da67a16614d532ad1beb5ede5848156.png
正常访问

而当我使用如下代码时发现也能正常访问网页:

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
​
@Component
@RequestMapping("")
public class DiffController {
​
    @RequestMapping("hello")
    @ResponseBody
    public Object hello(){
        return "hello world!";
    }
}

所以在Spring Boot 中只有被@Controller@RequestMapping注解时Spring才会去扫描内部的@RequestMapping,具体是在哪个版本加入的就后面有时间看看。

附录:环境

Spring Boot 2.4.0

Windows 10 1909 企业版

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值