Spring的Bean的生命周期与自动注入细节

1. Bean的生命周期

通过一个LifeCycleBean和一个MyBeanPostProcessor来观察Bean的生命周期:

构造(实例化)->依赖注入(前后处理)->初始化(前后处理)->销毁

LifeCycleBean

@Component
public class LifeCycleBean {
    private static final Logger log = LoggerFactory.getLogger(LifeCycleBean.class);

    //1.最先执行
    public LifeCycleBean(){
        log.info("构造");
    }

    //2.依赖注入
    @Autowired
//    public void autowire(@Value("${JAVA_HOME}")String home){ 这种方式好像要较新版本Spring才行
//        log.debug("依赖注入:{}", home);
//    }
    public void autowire(Bean1 bean1){
        log.info("依赖注入:{}", bean1);
    }

    //3.初始化
    @PostConstruct
    public void init(){
        log.info("初始化");}

    //4.销毁方法(仅在单例的时候调用, 其他scope调用时机不一样)
    @PreDestroy
    public void destroy(){log.info("销毁");}

}

MyBeanPostProcessor, 实现了InstantiationAwareBeanPostProcessor

@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
    private static final Logger log = LoggerFactory.getLogger(MyBeanPostProcessor.class);

    // 实例化之前
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")) {
            log.info("初始化之前执行, 这里返回的bean会替换原版本的bean");
        }
        return null;
    }
    // 实例化之后
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")) {
            log.info("实例化之后执行, 这里返回false会跳过依赖注入阶段");
            //return false;
        }
        return true;
    }

    // 依赖注入阶段执行
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if(beanName.equals("lifeCycleBean")){
            log.info("依赖注入阶段执行, 如@Autowired, @Value, @Resource");
        }
        return pvs;
    }


    // 初始化之前
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if(beanName.equals("lifeCycleBean")){
            log.info("初始化之前执行, 这里返回的对象会替换原本的bean, 如@PostConstruct, @ConfigurationProperties");
        }
        return bean;
    }

    // 初始化之后执行
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")) {
            log.info("初始化之后执行, 这里返回的对象会替换原本的bean, 如代理增强");
        }
        return bean;
    }


    // 销毁之前
    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        if(beanName.equals("lifeCycleBean")){
            log.info("销毁之前执行, 如 @PreDestroy");
        }
    }

}

运行结果:

[main]: 初始化之前执行, 这里返回的bean会替换原版本的bean --- postProcessBeforeInstantiation
[main]: 构造
[main]: 实例化之后执行, 这里返回false会跳过依赖注入阶段 --- postProcessAfterInstantiation
[main]: 依赖注入阶段执行,@Autowired, @Value, @Resource --- postProcessProperties
[main]: 依赖注入:com.yadong.springsourcestudy.chapter2.Bean1@21c64522
[main]: 初始化之前执行, 这里返回的对象会替换原本的bean,@PostConstruct, @ConfigurationProperties --- postProcessBeforeInitialization
[main]: 初始化
[main]: 初始化之后执行, 这里返回的对象会替换原本的bean, 如代理增强 --- postProcessAfterInitialization
[main]: 销毁之前执行,@PreDestroy --- postProcessBeforeDestruction
[main]: 销毁

2. @Autowired依赖注入的处理细节

依赖注入依靠AutowiredAnnotationBeanPostProcessor通过容器调用processor.postProcessProperties()执行依赖注入,

其过程是postProcessProperties()->InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs)

->metadata.inject(bean, beanName, pvs);

这个过程找了需要@Autowired的字段或方法后, 需要一些解析器来解析, 如 ContextAnnotationAutowireCandidateResolver, StandardEnvironment()::resolvePlaceholders

以下是一个手动调用解析@Autowired的过程:

public class AutowiredAnnotationBPP {

    public static void main(String[] args) throws Throwable {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); //解析@Value
        beanFactory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders);   //解析${}

        beanFactory.registerSingleton("bean2", new Bean2());
        beanFactory.registerSingleton("bean3", new Bean3());
        //1. 查找有哪些属性方法加了@Autowire, 这称之为InjectionMetadata
        AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
        processor.setBeanFactory(beanFactory);
        Bean1 bean1 = new Bean1();
        Method findAutowiringMetadata = AutowiredAnnotationBeanPostProcessor.class.getDeclaredMethod("findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
        findAutowiringMetadata.setAccessible(true);
        InjectionMetadata metadata = (InjectionMetadata) findAutowiringMetadata.invoke(processor, "bean1", Bean1.class, null);
        System.out.println("metadata = " + metadata);
        //2. metadata中存储了该bean要autowire的字段,方法等信息, 调用inject完成依赖注入
        metadata.inject(bean1, "bean1", null);
        System.out.println(bean1);
        
        //以下是要查找注入对象的过程
        Field bean2 = Bean1.class.getDeclaredField("bean2");
        DependencyDescriptor dd1 = new DependencyDescriptor(bean2, false);
        Object o = beanFactory.doResolveDependency(dd1, null, null, null);
        System.out.println(o);

        Method setBean2 = Bean1.class.getDeclaredMethod("setBean3", Bean3.class);
        DependencyDescriptor dd2 = new DependencyDescriptor(new MethodParameter(setBean2, 0), false);
        Object o1 = beanFactory.doResolveDependency(dd2, null, null, null);
        System.out.println(o1);

    }
}

//Bean1.java
@Component
public class Bean1 {

    @Autowired
    Bean2 bean2;

    Bean3 bean3;

    @Autowired
    public void setBean3(Bean3 bean3){
        this.bean3 = bean3;
    }
}

3. 常见后置处理器

  1. ConfigurationClassPostProcessor 能解析@ComponentScan, @Bean, @Import, @ImportResource

  2. MapperScannerConfigurer 解析@MapperScanner, SSM中用, SpringBoot已经实现了自动装配因此用不上

  3. AutowiredAnnotationBeanPostProcessor 解析@Autowire

4. 自实现ComponentScanPostProcessor

public class Chapter4Application {
    public static void main(String[] args) throws IOException {
        // 干净的容器
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("config", Config.class);
		// 自己实现的, 解析@ComponentScan
        context.registerBean(ComponentScanPostProcessor.class);

        context.refresh();

        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }

        context.close();
    }
}

// 自己实现的ComponentScanPostProcessor
public class ComponentScanPostProcessor implements BeanFactoryPostProcessor {

    // 在 context.refresh()时, 读取bd后, 实例化bean前, 会调用这个方法
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        try{
            ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
            if(componentScan != null){
                for (String p : componentScan.basePackages()) {
                    System.out.println(p);
                    // com.yadong.springsourcestudy.chapter4 -> classpath*:com/yadong/springsourcestudy/chapter4/**/*.class
                    String path = "classpath:*" + p.replace(".", "/") + "/**/*.class";
                    CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();  //读取资源的元信息
                    System.out.println(path);
                    Resource[] resources = new PathMatchingResourcePatternResolver().getResources(path);
                    AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
                    for (Resource resource : resources) {
                        System.out.println(resource);
                        MetadataReader metadataReader = factory.getMetadataReader(resource);
                        ClassMetadata classMetadata = metadataReader.getClassMetadata();
                        System.out.println("类名:" + classMetadata.getClassName());
                        //hasMetaAnnotation间接继承的注解也会扫描到
                        System.out.println("是否加了 @Component " + metadataReader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName()));
                        if(metadataReader.getAnnotationMetadata().hasAnnotation(Component.class.getName())
                                || metadataReader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName())){
                            AbstractBeanDefinition bd = BeanDefinitionBuilder
                                    .genericBeanDefinition(metadataReader.getClassMetadata().getClassName())
                                    .getBeanDefinition();
                            DefaultListableBeanFactory beanFactory = null;
                            if (configurableListableBeanFactory instanceof DefaultListableBeanFactory) {
                                beanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
                            }
                            String bdn = generator.generateBeanName(bd, beanFactory);
                            beanFactory.registerBeanDefinition(bdn, bd);
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浔汐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值