JAVA && Spring && SpringBoot2.x — 学习目录
Spring支持我们通过代码来将指定的类注册到spring容器中。其本质就是一个钩子方法。Spring源码会执行我们自定义的类,来进行对IOC容器中bean对象的增删改查。
(1)org.springframework.context.support.AbstractApplicationContext#refresh
方法中,调用了invokeBeanFactoryPostProcessors()
方法,BeanFactory的后置处理器,这些后处理器是在Bean定义时向容器中注册的。
(2)通过invokeBeanFactoryPostProcessors()
普瑞赛色
方法找出所有的BeanFactory的后置处理器(即BeanFactoryPostProcessor接口实现类),并且调用这些处理器来改变bean的定义。
(3)BeanDefinitionRegistryPostProcessor
实现了BeanFactoryPostProcessor接口,可以改变bean的定义,并且可以进行对bean进行注册和删除。
BeanDefinitionRegistryPostProcessor的定义:
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
//1. 继承 BeanFactoryPostProcessor的postProcessBeanFactory方法,可以改变Bean的定义
//2. postProcessBeanDefinitionRegistry方法可以注册、移除Bean到IOC容器中
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
2. 实战
1. 普通Bean类:
@Data
@Slf4j
public class Student {
private String id;
private String name;
public void init(){
log.info("【这是初始化方法...】");
}
}
2. 实现BeanDefinitionRegistryPostProcessor接口的类:
@Component
@Slf4j
public class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
public MyBeanFactoryPostProcessor() {
log.info("【开始执行 BeanFactoryPostProcessor】");
}
/**
* 动态修改Bean信息
*
* @param beanFactory
* @throws BeansException
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
log.info("【修改Bean对象】");
//获取Controller注解的Bean对象
//获取BeanDefinition对象
BeanDefinition student = beanFactory.getBeanDefinition("student1");
//动态的修改属性值
student.getPropertyValues().add("name", "tom002");
}
/**
* 动态注册Bean信息
*
* @param registry
* @throws BeansException
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
log.info("【注册Bean对象】");
BeanDefinition beanDefinition = BeanDefinitionBuilder.
genericBeanDefinition(Student.class).
addPropertyValue("id", "001").
addPropertyValue("name", "tom001")
.setInitMethodName("init")
.setScope(BeanDefinition.SCOPE_SINGLETON)
.getBeanDefinition();
//普通方法创建BeanDefinition对象
/* BeanDefinition beanDefinition = new GenericBeanDefinition();
//注册信息
beanDefinition.setBeanClassName("com.processor.Student");
//设置属性(设置对象的属性值)
beanDefinition.getPropertyValues().add("id", "001");
beanDefinition.getPropertyValues().add("name", "tom");*/
//注册到容器中
registry.registerBeanDefinition("student1", beanDefinition);
}
}
BeanDefinition定义了Bean在IOC容器中的基本数据结构,BeanDefinition描述了一个Bean实例,包括属性值,构造方法参数值和继承自它的类的信息。在Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构存储。
BeanDefinition一般用于允许BeanFactoryPostProcessor
接口的实现类检索和修改Bean属性值和别的Bean的元数据。