一、概述
Spring IOC容器的扩展点是指在IOC加载的过程中,如何对即将要创建的bean进行扩展。
二、扩展点
2.1、BeanDefinitionRegistryPostProcessor
2.1.1、概述
BeanDefinitionRegistryPostProcessor是bean定义的后置处理器,在BeanDefinition加载后,实例化bean之前,调用 invokeBeanFactoryPostProcessors时进行扩展,通过改变BeanDefinition的定义信息进行扩展,源码如下:
2.1.2、继承结构
2.1.3、案例
2.1.3.1、ATM
/**
* @Author : 一叶浮萍归大海
* @Date: 2023/11/23 15:06
* @Description:
*/
@Slf4j
@Component(value = "atm")
public class ATM {
public int withdrawMoney(int money) {
log.info("取钱方法正在执行...");
if (money == 100) {
throw new RuntimeException("自定义的异常");
}
return money;
}
}
2.1.3.2、MySpringConfig
/**
* @Author : 一叶浮萍归大海
* @Date: 2023/11/23 15:29
* @Description:
*/
@Configuration
@ComponentScan(basePackages = {"org.star"})
public class MySpringConfig {
}
2.1.3.3、MyBeanDefinitionRegistryPostProcessor
/**
* @Author : 一叶浮萍归大海
* @Date: 2023/11/25 17:38
* @Description:
*/
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
/**
* 作用:动态注册BeanDefinition
* 调用时机:IOC加载时注册BeanDefinition的时候会调用
* @param registry the bean definition registry used by the application context
* @throws BeansException
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
RootBeanDefinition definition = new RootBeanDefinition(ATM.class);
// 设置ATM bean为多实例
definition.setScope("prototype");
registry.registerBeanDefinition("atm",definition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("atm");
// 将atm设置为懒加载,这样在容器启动时将不会创建bean,只有在getBean时才会创建对象
beanDefinition.setLazyInit(true);
}
}
2.1.3.4、AopFullAnnotationMainApp
/**
* @Author : 一叶浮萍归大海
* @Date: 2023/11/23 15:14
* @Description:
*/
@Slf4j
public class AopFullAnnotationMainApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MySpringConfig.class);
ATM atm1 = context.getBean("atm", ATM.class);
ATM atm2 = context.getBean("atm", ATM.class);
log.info("atm1:{},atm2:{},(atm1 == atm2):{}", atm1,atm2,(atm1 == atm2));
}
}
2.2、xxxAware接口
2.2.1、概述
Spring中存在着大量的xxxAware接口实现类,用于在bean初始化完成之前做一些前置操作,程序员可以自己实现xxxAware接口,重写里边的方法修改bean的定义信息,进行扩展。
2.2.2、继承结构
2.2.3、案例
2.2.3.1、ATM
同上。
2.2.3.2、MySpringConfig
同上。
2.2.3.3、MyApplicationContextAware
/**
* @Author : 一叶浮萍归大海
* @Date: 2023/11/25 18:51
* @Description:
*/
@Component
public class MyApplicationContextAware implements ApplicationContextAware {
public ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
AnnotationConfigApplicationContext context = (AnnotationConfigApplicationContext) applicationContext;
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("atm");
beanDefinition.setScope("singleton");
}
}
2.2.3.4、AopFullAnnotationMainApp
同上。
2.2.3、调用链路
2.2.4、注意事项
通过观察 2.1.3.4和 2.2.3.4的执行结果,不能发现xxxAware接口中配置的扩展覆盖了BeanDefinitionRegistryPostProcessor中的配置,说明xxxAware的优先级更高,这个也很好理解,对于同样的一个bean,后边的配置肯定会覆盖掉前边的配置。
2.3、生命周期回调时进行扩展
a、@PostConstruct @PreDestroy
b、实现接口 InitializingBean, DisposableBean的方式
c、@Bean(initMethod = "init",destroyMethod = "destroy")的方式