Spring后处理器

目录

前言

 加载时机图解

一、bean工厂后处理器

1.BeanFactoryPostProcessor接口

案例

(1)配置文件:

 (2)模拟业务层代码:

 (3)自定义的处理器:

 (4)控制台打印:

2.BeanDefinitionRegistryPostProcessor接口

案例

(1)配置文件:

 (2)模拟业务层代码:

 (3)自定义的处理器:

 (4)控制台打印:

二、bean后处理器

1.BeanPostProcessor接口

案例

(1)配置文件:

(2)模拟业务层代码:

(3)自定义的处理器:

(4)控制台打印:


前言

Spring的后处理器是spring对外开放的重要扩展点,允许我们介入到bean的创建过程,以达到动态注册、修改BeanDefinition对象,以及动态修改bean的作用,后处理器主要两种:

⚫ BeanFactoryPostProcessor:bean工厂后处理器,在BeanDefinitionMap填充完毕,bean实例化之前执行
⚫ BeanPostProcessor:bean后处理器,一般在bean实例化之后,填充到单例池singletonObjects之前执行

 加载时机图解

 

提示:以下是本篇文章正文内容,下面案例可供参考

一、bean工厂后处理器

1.BeanFactoryPostProcessor接口

BeanFactoryPostProcessor是一个接口规范,实现了该接口的类交由Spring管理的话,那么Spring就会回调该接口的方法,实现对BeanDefinition的注册和修改

@FunctionalInterface
public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

案例

(1)配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- bean对象-->
    <bean id="userService" class="com.jh.service.UserServiceImpl"></bean>

    <!-- 自定义的后处理器   -->
    <bean id="myBeanFactoryPostProcessor" class="com.jh.postProcessor.MyBeanFactoryPostProcessor"></bean>

</beans>
 (2)模拟业务层代码:
public class UserServiceImpl implements UserService {

    public void save() {
        System.out.println("service层的save方法执行.........");
    }

}
 (3)自定义的处理器:
/**
 *  自定义后处理器方式一:实现BeanFactoryPostProcessor接口
 */
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    /**
     * 实现postProcessBeanFactory方法
     * @param configurableListableBeanFactory
     * @throws BeansException
     */
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("后处理器执行........");
    }
}
 (4)控制台打印:

2.BeanDefinitionRegistryPostProcessor接口

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean definition registry after its
	 * standard initialization. All regular bean definitions will have been loaded,
	 * but no beans will have been instantiated yet. This allows for adding further
	 * bean definitions before the next post-processing phase kicks in.
	 * @param registry the bean definition registry used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子类接口,可以用于注册BeanDefinition对象 

案例

(1)配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context.xsd">

 
<!--    <bean id="userService" class="com.jh.service.UserServiceImpl"></bean>-->

    <!-- 自定义的后处理器  -->
    <bean id="MyBeanDefinitionRegistryPostProcessor" class="com.jh.postProcessor.MyBeanDefinitionRegistryPostProcessor"></bean>

</beans>
 (2)模拟业务层代码:
public class UserServiceImpl implements UserService {

    public void save() {
        System.out.println("service层的save方法执行.........");
    }

}
 (3)自定义的处理器:
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    /**
     * 该方法会被spring容器自动识别
     * @param registry
     * @throws BeansException
     */
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("将userService对象注册到容器中....");
        //创建BeanDefinition对象
        BeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setBeanClassName("com.jh.service.UserServiceImpl");
        //注册对象
        registry.registerBeanDefinition("userService",beanDefinition);
    }

    /**
     * 父接口BeanFactoryPostProcessor的方法
     * @param beanFactory
     * @throws BeansException
     */
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("postProcessBeanFactory方法执行了.......");
    }
}
 (4)控制台打印:

我们可以看到,userService并没有在配置文件中配置,而是通过手动注册的方式加入到spring容器中

二、bean后处理器

1.BeanPostProcessor接口

public interface BeanPostProcessor {

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


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

}

bean被实例化后,到最终缓存到名为singletonObjects单例池之前,中间会经过bean的初始化过程,属性填充,初始化方法init执行等,其中有一个对外扩展的点BeanPostProcessor,我们称为bean后处理,跟上面的bean工厂后处理器类似。该接口有两个默认方法。

案例

(1)配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="userService" class="com.jh.service.UserServiceImpl" init-method="init" destroy-method="destroy">
        <property name="userName" value="案例"></property>
    </bean>

    <!-- 自定义的bean后处理器   -->
    <bean id="MyBeanPostProcessor" class="com.jh.postProcessor.MyBeanPostProcessor"></bean>

</beans>
(2)模拟业务层代码:

添加了无参构造方法、初始化方法、销毁方法,在控制台里可以清晰地看到执行顺序

public class UserServiceImpl implements UserService {


    private String userName;

    public void setUserName(String userName) {
        this.userName = userName;
        System.out.println("set方法执行...."+userName);
    }

    public UserServiceImpl(){
        System.out.println("UserServiceImpl无参构造方法执行了....");
    }

    public void init(){
        System.out.println("初始化方法执行.....");
    }

    public void destroy(){
        System.out.println("销毁方法执行.......");
    }

    public void save() {
        System.out.println("service层的save方法执行.........");
    }

}
(3)自定义的处理器:
/**
 * 自定义Bean后处理器
 */
public class MyBeanPostProcessor implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("bean对象:"+beanName+"方法:postProcessBeforeInitialization执行了....");
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("bean对象:"+beanName+"方法:postProcessAfterInitialization....");
        return bean;
    }
}
(4)控制台打印:

可以清楚的看到postProcessBeforeInitialization方法是在无参构造方法和set方法之后,初始化方法之前执行的,而postProcessAfterInitialization方法则是在初始化方法之后

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值