揭秘Spring(二)之BeanFactoryProcessor

在上一节中,我们说到了BeanFactory是较为轻量的容器,这个容器启动时会通过BeanDefinitionReader来加载配置文件获得对应BeanDefinition,然后将BeanDefinition注册到BeanDefinitionRegistry。这些是容器启动所做的工作,下一阶段就该实例化了。

如果当前使用的容器是BeanFactory,那么在getBean()时才会实例化;

如果使用ApplicationContext,如果bean的scope是singleton的,并且lazy-init为false(默认是false,所以可以不用设置),则ApplicationContext启动的时候就实例化该Bean,并且将实例化的Bean放在一个map结构的缓存中,下次再使用该Bean的时候,直接从这个缓存中取;如果bean的scope是singleton的,并且lazy-init为true,则该Bean的实例化是在第一次使用该Bean的时候进行实例化;如果bean的scope是prototype的,则该Bean的实例化是在第一次使用该Bean的时候进行实例化

OK,弄明白上边两个阶段后,我们引入今天的话题,容器的扩展机制。BeanFactoryProcessor允许我们在上述第一个阶段结束对最后生成BeanDefinition做出修改。

BeanFactoryProcessor

public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}
复制代码

BeanFactoryProcessor接口很简单,只有一个方法,方法名字也很显义,即BeanFactory的后处理工作,那么参数中的BeanFactory就是我们要处理的BeanFactory了。

// 这里我们使用BeanFactory的子接口
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}

// 定义了一个继承自BeanDefinitionRegistryPostProcessor的处理器,作用是创建student的BeanDefinition并进行注册
public class BfProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        // 第一次从所有befinition中找不到student
        System.out.println(registry.getBeanDefinition("student"));
        // 创造student的beandefinition
        BeanDefinitionHolder holder = createBeanDefinition(Student.class.getName());
        // 注册
        BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
        // 此时有了
        System.out.println(registry.getBeanDefinition("student"));
    }
    
    // 生产student的beandefinition
    private BeanDefinitionHolder createBeanDefinition(String className) {
        BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(Student.class);
        definition.addPropertyValue("name", "ffbbb");
        return new BeanDefinitionHolder(definition.getBeanDefinition(), "student");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
    }
}
复制代码

我们在上边这段代码中定义了一个继承自 BeanDefinitionRegistryPostProcessor 的后处理器 BfProcessor,将它注册到容器中

@Configuration
public class config {

    @Bean
    public User user(){
        return new User(100,"bbf");
    }

    @Bean
    public BfProcessor bfProcessor(){
        return new BfProcessor();
    }
}

@Data
public class Student {
    private String name;
}
复制代码

同时可以看到,我们并没有把Student进行注册,所以正常情况下容器初始化完成不会有Student的,接着, 我们的后处理器开始发挥作用,在第一遍扫描不到student后开始生产student的beandefinition,然后注册到registry,所以第二次扫描时可以扫描到student的beandefinition,此时的beandefinition只是元数据,并没有被实例化还,正如我们前面说过的,还没到实例化的阶段,底下这一长行就是该beandefinition。

Generic bean: class [com.example.springdemo.Bean.Student]; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
复制代码

总结

一个很简单的小例子,我们可以看到BeanFactoryProcessor中主要是针对beandefinition做一些工作,同时注意不要混淆BeanDefinition和真正的bean。


个人公众号

揭秘Spring(二)之BeanFactoryProcessor

原文 

https://juejin.im/post/5dc3d80cf265da4d044e3e14

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 揭秘Spring(二)之BeanFactoryProcessor

赞 (0)
分享到:更多 ()

评论 0

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