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

相关推荐
暮乘白帝过重山12 分钟前
Singleton和Prototype的作用域与饿汉式/懒汉式的初始化方式
spring·原型模式·prototype·饿汉式·singleton·懒汉式
腥臭腐朽的日子熠熠生辉41 分钟前
解决maven失效问题(现象:maven中只有jdk的工具包,没有springboot的包)
java·spring boot·maven
ejinxian42 分钟前
Spring AI Alibaba 快速开发生成式 Java AI 应用
java·人工智能·spring
杉之1 小时前
SpringBlade 数据库字段的自动填充
java·笔记·学习·spring·tomcat
圈圈编码1 小时前
Spring Task 定时任务
java·前端·spring
俏布斯1 小时前
算法日常记录
java·算法·leetcode
27669582921 小时前
美团民宿 mtgsig 小程序 mtgsig1.2 分析
java·python·小程序·美团·mtgsig·mtgsig1.2·美团民宿
爱的叹息1 小时前
Java 连接 Redis 的驱动(Jedis、Lettuce、Redisson、Spring Data Redis)分类及对比
java·redis·spring
程序猿chen2 小时前
《JVM考古现场(十五):熵火燎原——从量子递归到热寂晶壁的代码涅槃》
java·jvm·git·后端·java-ee·区块链·量子计算
松韬2 小时前
Spring + Redisson:从 0 到 1 搭建高可用分布式缓存系统
java·redis·分布式·spring·缓存