系列十六、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")的方式

相关推荐
_oP_i10 分钟前
Oracle JDK(通常简称为 JDK)和 OpenJDK区别
java·数据库·oracle
seabirdssss10 分钟前
力扣_876. 链表的中间结点
java·数据结构·算法·leetcode·链表
SEO-狼术10 分钟前
Enhance your XML editing experience Crack
xml·java·前端
IT-sec16 分钟前
tomcat 文件上传 (CVE-2017-12615)
java·安全·web安全·网络安全·tomcat·系统安全
i7i8i9com23 分钟前
baomidou Mabatis plus引入异常
java·开发语言·mybatis
weixin_4467077431 分钟前
使用easyexcel导出复杂模板,同时使用bean,map,list填充
java·excel·easyexcel
通义灵码37 分钟前
如何用通义灵码快速绘制流程图?
java·python·流程图·visual studio·通义灵码
小蒜学长41 分钟前
springboot视频网站系统的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端·spring
续写少年!1 小时前
自定义注解
java·开发语言
请你打开电视看看1 小时前
结构型模式-桥接模式
java·python·桥接模式