转载

揭秘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
正文到此结束
Loading...