Spring后置处理器(BeanPostProcessor)(BeanFactoryPostProcessor)

19 篇文章 5 订阅
12 篇文章 2 订阅

Spring的后置处理器,在应用Spring框架开发中非常重要,Spring底层的核心,就通过各种后置处理器去完成IOC容器的启动,AOP代理对象的创建。

Spring的后置处理器有两大类,BeanFactoryBean


BeanFactory

Bean 工厂方面的后置处理器

  • BeanFactoryPostProcessor 获取IOC容器
  • BeanDefinitionRegistryPostProcessor 向容器注册Bean

1:BeanFactoryPostProcessor
可以拿到Spring的IOC容器。ConfigurableListableBeanFactory

void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

2:BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistry Spring注册Bean的工具类,可以向容器手动注册Bean。

void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

例如:
在这里插入图片描述



Bean

Bean 方面的后置处理器

  • SmartInstantiationAwareBeanPostProcessor 设置Bean的类型,构造函数
  • InstantiationAwareBeanPostProcessor Bean实例化之前,属性赋值之前的处理器
  • MergedBeanDefinitionPostProcessor 再添加或修改Bean的定义信息
  • BeanPostProcessor Bean初始化之后的处理器,所有后置处理器的顶级接口。可以修改Bean实例的信息,甚至修改Bean的引用指向。

1:SmartInstantiationAwareBeanPostProcessor
设置Bean的类型,构造函数。基于Spring开发框架使用,平时开发不要使用。

public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
    /**
     * 设置 Bean 的类型
     */
    default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }
    /**
     * 设置创建 Bean用到的 构造函数
     */
    @Nullable
    default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
            throws BeansException {

        return null;
    }
    /**
     * 循环引用从此处获取 Bean实例
     */
    default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

假如在创建一个UserService.class的Bean,如下我指定成EmployeeService.class,构造函数也是EmployeeService的无参构造函数,那么创建UserService Bean实例就会变成 EmployeeService的实例。

default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
        if (beanName.equals("userService")) {
            return EmployeeService.class;
        }
        return null;
    }
    /**
     * 设置创建 Bean用到的 构造函数
     */
    @Nullable
    default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
            throws BeansException {
        if (beanName.equals("userService")) {
            try {
                return new Constructor[]{EmployeeService.class.getConstructor()};
            } catch (Exception e) {
            }
        }
        return null;
    }

2:InstantiationAwareBeanPostProcessor
postProcessBeforeInstantiation:Bean实例化之前执行此方法,如果返回不为null,则替代当前准备实例化的Bean,Spring将不再自动实例化对象了。
postProcessAfterInstantiation:如果返回 true,执行 postProcessProperties方法。
postProcessProperties:设置实例化Bean需要的属性,调用 set 方法赋值,如果指定的属性名没有set方法,则报错。

/**
     * 在Spring实例化Bean之前调用,该方法如果返回结果不为空,
     * 这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。
     * 如果该方法的返回值代替原本该生成的目标对象,
     * 后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走
     *
     * @param beanClass     Spring当前正在创建的Bean的类型
     * @param beanName      Spring当前正在创建的Bean的name
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }

    /**
     * 在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。
     *
     * 如果返回 true 调用 postProcessProperties设置属性值,然后 set 方法赋值
     * @return
     * @throws BeansException
     */
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if (beanName.equals("userService")) {
            return true;
        }
        return false;
    }
    /**
     * 设置属性值  为 Bean的 set 方法赋值
     *
     * 例如 添加了一个属性 password,会调用 bean的 setPassword方法,如果该方法没有,会报错
     */
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (beanName.equals("userService")) {
            ( (MutablePropertyValues) pvs).addPropertyValue(new PropertyValue("password", "123"));
            return pvs;
        }
        return null;
    }

3:MergedBeanDefinitionPostProcessor 再添加或修改Bean的定义信息

/**
     * @param beanDefinition 当前正在创建Bean的定义信息,可以用它再添加或修改一些定义信息
     *                       beanDefinition.setLazyInit(true); 设置懒加载为 true
     */
    void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

    /**
     * 如果修改了当前正在创建的Bean的 name 会执行
     * @param beanName
     */
    default void resetBeanDefinition(String beanName) {
    }

4:BeanPostProcessor
postProcessBeforeInitialization Bean初始化方法之前执行,可以返回一个对象,替代Spring当前的Bean实例。

postProcessAfterInitialization Bean初始化最后的一个处理方法,可以返回一个对象,替代Spring当前的Bean实例。AOP代理在此创建

	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
	
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

Spring底层源码的总结:

看过Spring源码的,就会知道Spring的启动流程,只是提供了一个注册特定的组件(后置处理器),及实例化Bean的模板功能。其他功能:依赖注入,AOP切面,事务管理,异步执行…等等一系列的拓展功能,都是在后置处理器中执行。所以要学好Spring,就必选要搞懂它提供的后置处理器功能。

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Me_Liu_Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值