Spring系列14:IoC容器的扩展点

本文详细讲解了Spring IoC容器的扩展点,重点分析了BeanPostProcessor接口,包括它的作用、定义、自定义实现以及使用@Order控制执行顺序。此外,还提到了PropertySourcesPlaceholderConfigurer和FactoryBean的概念和应用,帮助读者深入理解Spring容器的扩展机制。
摘要由CSDN通过智能技术生成

Spring系列14:IoC容器的扩展点

回顾

知识需要成体系地学习,本系列文章前后有关联,建议按照顺序阅读。上一篇我们详细介绍了Spring Bean的生命周期和丰富的扩展点,没有阅读的强烈建议先阅读。本篇来详细讲讲容器提供的扩展点,完整的生命周期图镇楼。

image-20220120101935737

本文内容

  1. 详解BeanPostProcessor
  2. 详解BeanFactoryPostProcessor
  3. 详解FactoryBean

详解BeanPostProcessor

作用和定义

常规 BeanPostProcessor 的作用是提供自定义的实例化逻辑、初始化逻辑、依赖关系解析逻辑等,对bean进行增强。主要的作用阶段是初始阶段前后。该接口定义了2接口,分别是前置增强和后置增强。 Spring AOP 功能主要是通过 BeanPostProcessor 实现的。

public interface BeanPostProcessor {
    // 在任何 bean 初始化回调(如 InitializingBean 的 afterPropertiesSet 或自定义 init 方法)之前     // 将此 BeanPostProcessor 应用于给定的新 bean 实例。 bean 将已填充属性值。返回的 bean 实例可能是     // 原始的包装器。默认实现按原样返回给定的 bean
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    // 在任何 bean 初始化回调(如 InitializingBean 的 afterPropertiesSet 或自定义 init 方法)之          // 后,将此 BeanPostProcessor 应用于给定的新 bean 实例。 bean 将已填充属性值。返回的 bean 实例可     /// 能是原始的包装器。默认实现按原样返回给定的 bean
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}
自定义BeanPostProcessor

自定义一个 BeanPostProcessor 实现,该实现调用每个 bean 的 toString() 方法打印内容输出到控制台。

类定义如下

/**
 * @author zfd
 * @version v1.0
 * @date 2022/1/20 11:21
 * @关于我 请关注公众号 螃蟹的Java笔记 获取更多技术系列
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 返回原始bean
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println( bean + " 名称是: " + beanName);
        return bean;
    }
}

@Component("xxxBeanOne")
public class BeanOne {
}


@Configuration
@ComponentScan
public class AppConfig {
}

测试程序及结果

@org.junit.Test
public void test1() {
    AnnotationConfigApplicationContext context =
            new AnnotationConfigApplicationContext(AppConfig.class);
    BeanOne bean = context.getBean(BeanOne.class);
    System.out.println(bean);
    context.close();
}
// 结果
com.crab.spring.ioc.demo12.AppConfig$$EnhancerBySpringCGLIB$$da23c216@4445629 名称是: appConfig
com.crab.spring.ioc.demo12.BeanOne@45b9a632 名称是: xxxBeanOne
com.crab.spring.ioc.demo12.BeanOne@45b9a632

从结果看,MyBeanPostProcessor#postProcessAfterInitialization 输出了容器内初始化bean的名称。

使用 @Order 控制 BeanPostProcessor 执行顺序

实际程序程序中肯定存在多个 BeanPostProcessor 通过 @Order 来指定顺序。

增加 MyBeanPostProcessor2 指定顺序是 -2

@Component
@Order(-2)
public class MyBeanPostProcessor2 implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 返回原始bean
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyBeanPostProcessor2 输出:" +  bean + " 名称是: " + beanName);
        return bean;
    }
}

同样的测试程序,观察下结果

com.crab.spring.ioc.demo12.AppConfig$$EnhancerBySpringCGLIB$$6fb51f6@54c562f7 名称是: appConfig
MyBeanPostProcessor2 输出:com.crab.spring.ioc.demo12.AppConfig$$EnhancerBySpringCGLIB$$6fb51f6@54c562f7 名称是: appConfig
com.crab.spring.ioc.demo12.BeanOne@318ba8c8 名称是
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值