Spring源码-04

本文详细剖析了Spring中Bean的后置处理器,包括@Autowired和@ConfigurationProperties的执行流程,通过实例展示了如何在`GenericApplicationContext`中注册和使用这些处理器,以及它们如何驱动依赖注入和配置属性的处理。
摘要由CSDN通过智能技术生成

文章目录


一、Bean的后置处理器

@Component
public class Test03 {
    public static void main(String[] args) {
        //GenericApplicationContext 是一个干净的容器
        GenericApplicationContext context = new GenericApplicationContext();
        //用原始方法注册三个bean
        context.registerBean("bean1",Bean1.class);
        context.registerBean("bean2",Bean2.class);
        context.registerBean("bean3",Bean3.class);
        context.registerBean("bean4",Bean4.class);

        //解决@Value String问题
        context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        //@Autowired @Value
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
        //@Resource @PostConstruct @PreDestroy
        context.registerBean(CommonAnnotationBeanPostProcessor.class);
        //@ConfigurationProperties
        ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory());

        //初始化容器
        context.refresh();

        System.out.println(context.getBean(Bean4.class).toString());

        //销毁容器
        context.close();
    }
}

class Bean1{
    private Bean2 bean2;
    @Autowired
    public void setBean2(Bean2 bean2){
        System.out.println("@Autowired生效");
        this.bean2=bean2;
    }
    private Bean3 bean3;
    @Resource
    public void setBean3(Bean3 bean3){
        System.out.println("@Resource生效");
        this.bean3=bean3;
    }
    private String javahome;
    @Autowired
    public void javahome(@Value("${JAVA_HOME}") String javahome){
        System.out.println("@Value生效");
        this.javahome=javahome;
    }
    @PostConstruct
    public void post(){
        System.out.println("@PostConstruct生效");
    }
    @PreDestroy
    public void pre(){
        System.out.println("@PreDestroy生效");
    }

    @Override
    public String toString() {
        return "Bean1{" +
                "bean2=" + bean2 +
                ", bean3=" + bean3 +
                ", javahome='" + javahome + '\'' +
                '}';
    }
}
class Bean2{

}
class Bean3{
}
@Data
@ConfigurationProperties(prefix = "java")
class Bean4{
    private String home;
    private String version;
}

二、@Autowired Bean后置处理器执行分析

@Component
public class Test03 {
    public static void main(String[] args) throws Throwable {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        //忽略创建过程、依赖注入、初始化
        factory.registerSingleton("bean2",new Bean2());
        factory.registerSingleton("bean3",new Bean3());
        //@Value String类型
        factory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        //${}的解析器
        factory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders);

        //查找哪些属性、方法加了@Autowired 这称之为 InjectionMetadata
        AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
        processor.setBeanFactory(factory);

        Bean1 bean1 = new Bean1();
//        System.out.println(bean1);
//        //执行依赖注入 @Autowired @Value
//        autowiredAnnotationBeanPostProcessor.postProcessProperties(null,bean1,"bean1");
//        System.out.println(bean1);

        //postProcessProperties步骤
        Method findAutowiringMetadata = AutowiredAnnotationBeanPostProcessor.class.getDeclaredMethod("findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
        findAutowiringMetadata.setAccessible(true);
        //获取bean1 上加了 @Value @Autowired 的成员变量,方法参数信息
        InjectionMetadata metadata = (InjectionMetadata) findAutowiringMetadata.invoke(processor, "bean1", Bean1.class, null);

        //InjectionMetadata 来进行依赖注入,注入时按类型查找
        metadata.inject(bean1,"bean1",null);
        System.out.println(bean1);
        

        //按照类型查找值
        Field bean2 = Bean1.class.getDeclaredField("bean2");
        DependencyDescriptor dependencyDescriptor = new DependencyDescriptor(bean2, false);
        Object o = factory.doResolveDependency(dependencyDescriptor, null, null, null);
        System.out.println(o);
    }
}

class Bean1{
    private Bean2 bean2;
    @Autowired
    public void setBean2(Bean2 bean2){
        System.out.println("@Autowired生效");
        this.bean2=bean2;
    }
    private Bean3 bean3;
    @Resource
    public void setBean3(Bean3 bean3){
        System.out.println("@Resource生效");
        this.bean3=bean3;
    }
    private String javahome;
    @Autowired
    public void javahome(@Value("${JAVA_HOME}") String javahome){
        System.out.println("@Value生效");
        this.javahome=javahome;
    }
    @PostConstruct
    public void post(){
        System.out.println("@PostConstruct生效");
    }
    @PreDestroy
    public void pre(){
        System.out.println("@PreDestroy生效");
    }

    @Override
    public String toString() {
        return "Bean1{" +
                "bean2=" + bean2 +
                ", bean3=" + bean3 +
                ", javahome='" + javahome + '\'' +
                '}';
    }
}
class Bean2{

}
class Bean3{
}
@Data
@ConfigurationProperties(prefix = "java")
class Bean4{
    private String home;
    private String version;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值