spring的bean周期中BeanPostProcessor浅析

参考:https://www.cnblogs.com/sishang/p/6576665.html

   https://www.jianshu.com/p/890446a3d477

1. 基本概念

spring容器在实例化bean之后(通过构造器创建对象并注入属性值即为实例化),可以使用BeanPostProcessor接口在bean的初始化方法前后根据需要做自己的逻辑处理。

2. BeanPostProcessor后置处理器的使用

BeanPostProcessor接口有两个方法,postProcessBeforeInitialization和postProcessAfterInitialization,默认情况下后置处理器会处理容器中所有的bean。

postProcessBeforeInitialization在bean初始化方法之前调用,初始化方法包括:bean标签添加init-method属性指定Java类中初始化方法、 @PostConstruct注解指定初始化方法,Java类实现InitailztingBean接口所产生的afterPropertiesSet()方法等。

postProcessAfterInitialization在bean初始化方法之后调用。

public class PostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean,
            String beanName) throws BeansException {
        if ("narCodeService".equals(beanName)) {//此方法获取容器中所有的bean,根据 beanName 名称选择要处理的bean,此处过滤实例ID为narCodeService
            
            return bean;
        }
        System.out.println("后置处理器处理bean=【"+beanName+"】开始");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean,
            String beanName) throws BeansException {
        if ("narCodeService".equals(beanName)) {
            return bean;
        }
        System.out.println("后置处理器处理bean=【"+beanName+"】完毕!");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return bean;
    }

}

上段代码两个方法的第一个参数为bean对象,第二个参数为bean对象的全称名称(包名加类名)。然后该实现类配置在spring配置文件中就可以使用了。多个后置处理器按照配置顺序执行,可以配置order属性进行设置优先级。

然后将PostProcessor注入到spring容器中,比如配置到application.xml文件中。

下面有个完成实例:

package renchaofeng;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class PostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if("messageService".equals(beanName)) {
			System.out.println("messageService init method after..");
		}
		if("testnreImpl".equals(beanName)) {
			System.out.println("testnreImpl init method after..");
		}
		return bean;
	}

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if("messageService".equals(beanName)) {
			System.out.println("messageService init method before..");
		}
		if("testnreImpl".equals(beanName)) {
			System.out.println("testnreImpl init method before..");
		}
		return bean;
	}
}

将 PostProcessor配置到spring容器中,

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName">

    <bean id="postProcessor" class="renchaofeng.PostProcessor"/>
    
    
</beans>

分别定义两个接口和其实现类:

package renchaofeng;

public interface MessageService {
	String getMessage();
}




package renchaofeng;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MessageServiceImpl implements MessageService,InitializingBean {

	public String getMessage() {
		return "hello world";
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("message init method...");
		
	}
}
package renchaofeng;

public interface Testnre {
 void getRen();
}


package renchaofeng;

import org.springframework.beans.factory.InitializingBean;

public class TestnreImpl implements Testnre,InitializingBean {

	@Override
	public void getRen() {
		 System.out.println("fffff..");

	}

	@Override
	public void afterPropertiesSet() throws Exception {
		 System.out.println("TestnreImpl init method..");
		
	}

}

 然后把上面两个实现类配置到spring容器中:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName">

    <bean id="messageService" class="renchaofeng.MessageServiceImpl"/>
    <bean id="postProcessor" class="renchaofeng.PostProcessor"/>
    <bean id="testnreImpl" class="renchaofeng.TestnreImpl"/>
    
</beans>

写个测试类如下:

package renchaofeng;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpring {
    public static void main(String[] args) throws BeansException{ 
    	 ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/application-ren.xml");
         System.out.println("context 启动成功");
         MessageService messageService = (MessageService)context.getBean("messageService");
         System.out.println(messageService.getMessage());
         
    }
}

 运行结果如下:

messageService init method before..
message init method...
messageService init method after..
testnreImpl init method before..
TestnreImpl init method..
testnreImpl init method after..
context 启动成功
hello world

说明每当一个bean执行初始化方法时,都会调用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法。

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值