欢迎光临
我们一直在努力

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;
}

工作流程剖析:

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

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

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

  • @Transactional — 声明式事务

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

  • @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管理业务类实例

    总结:

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

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

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

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

    赞(0)
    未经允许不得转载:171主机测评 » Spring核心注解全解析
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址