
前言:我们前面学习了Sping家族的相关框架,用的最多的就是注解了。里面有非常多的注解,我们常常会傻傻搞不清,那么我通过这篇文章让你拿下Spring家族的所有重要注解,并对一些注解进行源码解读。
注解 | 主要用途 | 所属框架 |
|---|---|---|
@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 |
注解 | 主要用途 | 所属框架 |
|---|---|---|
@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 |
注解 | 主要用途 | 所属框架 |
|---|---|---|
@Transactional | 声明方法或类的事务边界 | Spring |
@Entity | 标识一个JPA实体类 | JPA |
@Table | 指定实体类映射的数据库表名 | JPA |
@Id | 标识实体类的主键字段 | JPA |
@GeneratedValue | 指定主键的生成策略 | JPA |
@Column | 指定字段映射的数据库列名及属性 | JPA |
注解 | 主要用途 | 所属框架 |
|---|---|---|
@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 |
注解 | 主要用途 | 所属框架 |
|---|---|---|
@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;
}工作流程剖析:
refresh()时,会注册AutowiredAnnotationBeanPostProcessor。
postProcessMergedBeanDefinition(),扫描Bean中的@Autowired(字段/方法),将待注入的信息封装成InjectionMetadata对象。
populateBean()阶段,再次调用后置处理器的postProcessPropertyValues(),遍历InjectionMetadata。根据类型或名称(配合@Qualifier)从容器中查找依赖,通过反射暴力赋值
@Transactional — 声明式事务
@Transactional通过AOP实现,将复杂的事务管理逻辑与业务代码解耦
@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。
proxyBeanMethods = true,默认)@Bean标记的方法时,不会真的执行该方法,而是直接从Spring容器中(IoC单例池)获取已经创建好的单例Bean。
myService(),得到的都是同一个实例。
proxyBeanMethods = false)
@Component类。
@Bean方法时,方法体真的会被执行,每次都返回一个新的对象。
@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)。
如果对你有帮助,请一键三连,蟹蟹了