Spring框架中@Autowired、@Resource、@Inject注解实现原理是什么?

摘要:你知道Spring中的@Autowired,@Resource,@Inject 这些注解的实现原理么?
使用案例 前置条件: 现在有一个 Vehicle 接口,它有两个实现类 Bus 和 Car ,现在还有一个类 VehicleService 需要注入一个 Vehicle 类型的 Bean: public interface Vehicle {} @Component public class Car implements Vehicle {} @Component public class Bus implements Vehicle {} 使用 @Autowired 注解注入 Bean: @Autowired 注解可以和 @Qualifier 注解一起使用,在有多个符合条件的 Bean 的情况下限制注入特定名称的 Bean: @Component public class VehicleService { @Autowired @Qualifier("car") //假设这里是想要注入Bean名称为car的这个Bean private Vehicle vehicle; } 使用 @Inject 注解注入 Bean: @Inject 注解可以和 @Qualifier或者 @Named 注解一起使用,在有多个符合条件的 Bean 的情况下限制注入特定名称的 Bean: @Component public class VehicleService { @Inject @Qualifier("car") //假设这里是想要注入Bean名称为car的这个Bean private Vehicle vehicle; @Inject @Named("bus") //假设这里是想要注入Bean名称为bus的这个Bean private Vehicle anotherVehicle; } 使用 @Resource 注解注入 Bean: @Component public class VehicleService { @Resource(name = "car") private Vehicle vehicle; } 虽然以上三种使用方法都能够实现注入 Bean 的需求,但是它们在底层实现上有什么区别呢? 注解体系 在 Java EE 和 Spring 体系中定义了几套注解: JSR 250:定义了 @PostConstruct,@PreDestroy,@Resource 注解,其中 @Resource 注解默认是按照名称进行注入。 JSR 330:定义了 @Inject,@Qualifier, @Named 注解,其中 @Inject 注解默认是按照类型进行注入,可以搭配 @Qualifier 或者@Named 注解实现按照名称注入。 Spring:定义了 @Autowired,@Qualifier注解,其中 @Autowired 注解默认是按照类型进行注入,可以搭配 @Qualifier 注解实现按照名称注入。 当前 JSR 250 定义的注解属于 jakarta.annotation-api,而 JSR 330 定义的注解属于 jakarta.inject-api。 实现原理 InstantiationAwareBeanPostProcessor 方法调用触发的位置: Spring 中提供了 InstantiationAwareBeanPostProcessor 接口,它有一个 postProcessProperties() 负责实现对 Bean 的属性进行处理。 Spring 中提供了实现类 CommonAnnotationBeanPostProcessor 负责处理 @Resource 注解;提供了实现类 AutowiredAnnotationBeanPostProcessor 负责处理 @Autowired 注解和 @Inject 注解。 InstantiationAwareBeanPostProcessor的 postProcessProperties() 方法是在 AbstractAutowireCapableBeanFactory 中的 doCreateBean() 创建 Bean 的方法中触发调用的,在这个方法中的主要实现逻辑是实例化 Bean -> 填充 Bean 属性 -> 初始化 Bean。
阅读全文