系列十六、Spring IOC容器的扩展点

一、概述

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
java 复制代码
/**
 * @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
java 复制代码
/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/23 15:29
 * @Description:
 */
@Configuration
@ComponentScan(basePackages = {"org.star"})
public class MySpringConfig {

}
2.1.3.3、MyBeanDefinitionRegistryPostProcessor
java 复制代码
/**
 * @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
java 复制代码
/**
 * @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
java 复制代码
/**
 * @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")的方式

相关推荐
Chan164 分钟前
微服务 - Higress网关
java·spring boot·微服务·云原生·面试·架构·intellij-idea
二哈喇子!7 分钟前
JavaSE 与 JavaEE 知识点整合
java·servlet·tomcat
之歆13 分钟前
Spring AI入门到实战到原理源码-多模型协作智能客服系统
java·人工智能·spring
yyy(十一月限定版)26 分钟前
c++(3)类和对象(中)
java·开发语言·c++
IT 行者40 分钟前
Spring Security 7 OAuth2 Token 格式选择浅析
java·后端·spring
shughui43 分钟前
最新版IntelliJ IDEA下载+安装+汉化(详细图文)
java·ide·intellij-idea
小罗和阿泽1 小时前
java 【多线程基础 三】
java·开发语言
想你依然心痛1 小时前
从x86到ARM的HPC之旅:鲲鹏开发工具链(编译器+数学库+MPI)上手与实战
java·开发语言·arm开发·鲲鹏·昇腾
我的golang之路果然有问题1 小时前
积累的 java 找工作资源
java·笔记