Spring核心注解全解析

前言:我们前面学习了Sping家族的相关框架,用的最多的就是注解了。里面有非常多的注解,我们常常会傻傻搞不清,那么我通过这篇文章让你拿下Spring家族的所有重要注解,并对一些注解进行源码解读。

Spring & Spring Boot 核心注解速查表

注解 主要用途 所属框架
@Component 通用的Spring托管Bean注解 Spring
@Service 标识业务逻辑层(Service层)的组件 Spring
@Repository 标识数据访问层(DAO层)的组件,自带异常转换 Spring
@Controller 标识展现层(Web层)的组件 Spring MVC
@Configuration 标识一个类为Java配置类,可包含@Bean方法 Spring
@Bean 标注在方法上,将方法返回值注册为一个Bean Spring
@ComponentScan 配置组件扫描的路径 Spring
@Autowired 按类型自动装配依赖 Spring
@Qualifier @Autowired联用,按名称指定具体注入的Bean Spring
@Value 注入外部配置文件(如application.properties)的属性值 Spring
@Scope 定义Bean的作用域(如singleton、prototype) Spring
@Primary 当有多个相同类型的Bean时,优先注入被该注解标记的Bean Spring
@Import 导入一个或多个配置类 Spring
@PropertySource 加载指定的properties配置文件 Spring
@ConfigurationProperties 将配置文件中的属性绑定到一个POJO类上 Spring Boot
Spring MVC / Web 层开发
注解 主要用途 所属框架
@RestController @Controller + @ResponseBody的组合,用于RESTful API Spring MVC
@RequestMapping 映射URL路径到控制器类或方法上 Spring MVC
@GetMapping @RequestMapping(method = RequestMethod.GET)的简写 Spring MVC
@PostMapping @RequestMapping(method = RequestMethod.POST)的简写 Spring MVC
@PutMapping @RequestMapping(method = RequestMethod.PUT)的简写 Spring MVC
@DeleteMapping @RequestMapping(method = RequestMethod.DELETE)的简写 Spring MVC
@PathVariable 获取URL模板中的变量值 Spring MVC
@RequestParam 获取请求参数(Query String或Form数据) Spring MVC
@RequestBody 将HTTP请求体(JSON/XML)绑定到方法参数上 Spring MVC
@ResponseBody 将方法返回值直接写入HTTP响应体(如返回JSON) Spring MVC
@ControllerAdvice 全局处理控制器,用于异常处理、数据绑定等 Spring MVC
@ExceptionHandler 用于处理特定异常的注解 Spring MVC
数据访问(JPA / JDBC)
注解 主要用途 所属框架
@Transactional 声明方法或类的事务边界 Spring
@Entity 标识一个JPA实体类 JPA
@Table 指定实体类映射的数据库表名 JPA
@Id 标识实体类的主键字段 JPA
@GeneratedValue 指定主键的生成策略 JPA
@Column 指定字段映射的数据库列名及属性 JPA
高级特性与AOP
注解 主要用途 所属框架
@Aspect 标识一个类为切面类 Spring AOP
@Before 定义前置通知 Spring AOP
@After 定义后置通知 Spring AOP
@Around 定义环绕通知 Spring AOP
@Pointcut 定义切入点表达式 Spring AOP
@EnableAspectJAutoProxy 开启对AspectJ注解的支持 Spring AOP
@Async 声明一个方法为异步执行 Spring
@Scheduled 声明一个方法为定时任务 Spring
@Conditional及其派生注解 根据特定条件来决定是否创建Bean Spring Boot
@SpringBootApplication Spring Boot应用启动类核心注解(组合了@Configuration@EnableAutoConfiguration@ComponentScan Spring Boot
Spring Cloud 微服务
注解 主要用途 所属框架
@EnableEurekaServer 启动一个Eureka服务注册中心 Spring Cloud Netflix
@EnableDiscoveryClient 让服务实例能被服务发现组件(如Eureka、Consul)发现 Spring Cloud Commons
@LoadBalanced RestTemplate赋予客户端负载均衡能力(如Ribbon) Spring Cloud Commons
@FeignClient 声明一个声明式的HTTP客户端,用于调用其他微服务 Spring Cloud OpenFeign
@EnableCircuitBreaker / @EnableHystrix 开启断路器功能 Spring Cloud Netflix
@HystrixCommand 配置Hystrix命令的熔断和降级逻辑 Spring Cloud Netflix
@EnableConfigServer 启动Spring Cloud配置中心服务端 Spring Cloud Config
@RefreshScope 使配置类或Bean支持动态刷新配置 Spring Cloud Commons
@EnableZuulProxy 启用Zuul网关代理功能 Spring Cloud Netflix
@EnableResourceServer 启用OAuth2资源服务器功能 Spring Cloud Security
@PreAuthorize 方法级别的权限控制,基于表达式 Spring Security

注解源码分析

@Component

++@Component是所有被Spring管理的Bean的源头,像@Service@Repository等注解都派生自它++

源码:

复制代码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
    
    @AliasFor("value")
    String name() default "";

    @AliasFor("name")
    String value() default "";
}

设计分析

  • 元注解@Target(ElementType.TYPE)表示只能用于类(或接口);@Retention(RetentionPolicy.RUNTIME)确保注解在运行时可以通过反射读取,这是Spring容器工作的基础。

  • @Indexed:从Spring 5引入,用于构建候选组件索引,避免类路径扫描,从而提升大型项目的启动速度。

  • @AliasFor的双向别名value()name()互为别名,让开发者可以自由选择@Component("myBean")@Component(name="myBean"),API设计上更人性化。

@Autowired --- 依赖注入的核心

++@Autowired是依赖注入的入口。它本身只是一个标记,真正的工作是由AutowiredAnnotationBeanPostProcessor完成的。++

复制代码
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, 
         ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {

    boolean required() default true;
}

工作流程剖析

  1. 注册处理器 :Spring容器启动refresh()时,会注册AutowiredAnnotationBeanPostProcessor

  2. 预解析元数据 :在Bean实例化阶段,该后置处理器调用postProcessMergedBeanDefinition(),扫描Bean中的@Autowired(字段/方法),将待注入的信息封装成InjectionMetadata对象。

  3. 执行属性填充 :在populateBean()阶段,再次调用后置处理器的postProcessPropertyValues(),遍历InjectionMetadata。根据类型或名称(配合@Qualifier)从容器中查找依赖,通过反射暴力赋值

@Transactional --- 声明式事务

@Transactional通过AOP实现,将复杂的事务管理逻辑与业务代码解耦
5.

复制代码
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {

    @AliasFor("transactionManager")
    String value() default "";
    
    @AliasFor("value")
    String transactionManager() default "";
    
    Propagation propagation() default Propagation.REQUIRED;
    Isolation isolation() default Isolation.DEFAULT;
    boolean readOnly() default false;
    // ... 其他属性
  • 代理模式:Spring会为目标Bean创建代理对象(JDK动态代理或CGLIB)。调用@Transactional方法时,实际调用的是代理对象。

  • 拦截器链:TransactionInterceptor(事务拦截器)在代理中发挥作用,执行环绕通知。

  • 事务决断

@SpringBootApplication --- 一键启动

++@SpringBootApplication是一个复合注解,它将三个核心功能打包在一起,极大简化了配置++

  • @SpringBootConfiguration :本质是@Configuration,标记当前类是配置类。

  • @ComponentScan:启动自动扫描,默认扫描主类所在包及其子包。

  • @EnableAutoConfiguration核心中的核心 。它通过@Import(AutoConfigurationImportSelector.class)导入一大批自动配置类。AutoConfigurationImportSelector会读取META-INF/spring.factories文件,根据当前类路径下的依赖(如有无DataSource类)有选择地启用配置。

  • proxyBeanMethods属性 :默认为true,即Full模式 。此时Spring会通过CGLIB创建配置类的代理,确保@Bean方法间相互调用时是单例的,而非重新创建对象。

@Configuration

++@Configuration用于标记一个类为Spring的配置类。Spring IoC容器在启动时,会读取这个类中定义的方法,并根据这些方法来创建和组装Bean。++

  • @Component的派生@Configuration上标有@Component,这意味着所有带@Configuration的类本身也会被Spring容器当作一个Bean来管理。

  • proxyBeanMethods :这是理解@Configuration最核心 的开关,默认值为true

Full 模式 (proxyBeanMethods = true,默认)
  • 特点:Spring会通过CGLIB动态代理 创建一个配置类的代理对象。

  • 行为:当你调用配置类中被@Bean标记的方法时,不会真的执行该方法 ,而是直接从Spring容器中(IoC单例池)获取已经创建好的单例Bean

  • 意义:保证了Bean的单例性。无论你在代码中显式调用多少次myService(),得到的都是同一个实例。

Lite 模式 (proxyBeanMethods = false)
  • 特点:这是一个普通的Spring Bean ,不会经过CGLIB增强,就是一个普通的@Component类。

  • 行为:当你调用@Bean方法时,方法体真的会被执行,每次都返回一个新的对象。

  • 应用场景:适用于那些不需要在配置类内部通过方法调用相互引用的场景,例如简单的工具类配置,或者导入其他配置,可以减少启动开销。

  • Spring启动,扫描到@Configuration,创建AppConfig代理对象

  • 调用代理对象的myService()方法 -> 代理逻辑拦截 -> 检查容器中是否有MyService类型的Bean?

  • 如果没有,执行真正的new MyService(),放入容器,返回实例。

  • 调用代理对象的myController()方法,执行方法体,其中又调用了myService()

  • 再次调用myService()方法 -> 代理逻辑再次拦截 -> 此时容器中已经有MyService实例了,直接返回该实例,而不会再执行 new MyService()

  • MyController拿到了与之前完全相同的 MyService实例。

对比

维度 @Configuration @Component
角色 专门用于定义Bean的配置源 通用的Bean,用于业务逻辑
代理机制 默认有CGLIB代理,保证单例 无代理,就是个普通Bean
方法调用 @Bean方法间相互调用返回的是容器中的单例对象 @Bean方法间调用就是普通的Java方法调用,每次返回新对象
目的 替代XML,集中管理Bean定义 让Spring管理业务类实例

总结:

  1. 注解即标记:注解本身仅包含属性和元数据,不包含业务逻辑。

  2. 处理器负责干活 :真正的功能由各种*Processor(如AutowiredAnnotationBeanPostProcessor)、*Interceptor(如TransactionInterceptor)或*ImportSelector实现。

  3. 利用反射和代理 :核心实现手段是反射 (如@Autowired赋值)和动态代理 (如@Transactional@Configuration)。

如果对你有帮助,请一键三连,蟹蟹了

相关推荐
云深麋鹿2 小时前
标准库中的String类
开发语言·c++·容器
金牌归来发现妻女流落街头2 小时前
日志级别是摆设吗?
java·spring boot·日志
脱离语言3 小时前
Jeecg3.8.2 前端经验汇总
开发语言·前端·javascript
MOONICK3 小时前
C#基础入门
java·开发语言
女王大人万岁3 小时前
Golang标准库 CGO 介绍与使用指南
服务器·开发语言·后端·golang
myzzb3 小时前
纯python 最快png转换RGB截图方案 ——deepseek
开发语言·python·学习·开源·开发
t198751283 小时前
基于Chirp分解和多相快速算法的离散分数傅里叶变换(DFRFT)MATLAB实现
开发语言·算法·matlab
jllllyuz3 小时前
基于MATLAB的PAM通信系统仿真实现
开发语言·matlab
程序员小假3 小时前
我们来说一下虚拟内存的概念、作用及实现原理
java·后端