1、实现BeanFactoryPostProcessor 接口,会被Application contexts自动发现
2、BeanFactoryPostProcessor 仅仅对 bean definitions 发生关系,不能对bean instances 交互,对bean instances 的交互,由BeanPostProcessor的实现来处理
3、PropertyResourceConfigurer 是一个典型的实现
举例:
有这样的也个业务场景:
<bean id="user" class="com.gym.UserServiceImpl" > <property name="username" value="${username_}"/> <property name="password" value="${password_}"/> </bean>
spring支持系统对username_进行占位符的配置为properties文件配置,试想如果我们有个配置中心,我们希望spring启动的时候,从配置中心取数据,而非本地文件,这里就需要我们自定义一个实现BeanFactoryPostProcessor的PropertyResourceConfigurer 实例。
看下面的例子:
xml配置:
<?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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" default-autowire="byName"> <bean id="user" class="com.gym.UserServiceImpl" > <property name="username" value="${username_}"/> <property name="password" value="${password_}"/> </bean> <bean id="myFactoryPostProcessor" class="com.gym.MyFilePlaceHolderBeanFactoryPostProcessor"/> </beans>
模拟从远程取文件:
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.core.io.support.PropertiesLoaderUtils; /** * @author xinchun.wang */ public class MyFilePlaceHolderBeanFactoryPostProcessor extends PropertyPlaceholderConfigurer implements InitializingBean{ public void afterPropertiesSet() throws Exception { List<Properties> list = new ArrayList<Properties>(); Properties p = PropertiesLoaderUtils.loadAllProperties("config.properties"); list.add(p); //这里是关键,这就设置了我们远程取得的List<Properties>列表 setPropertiesArray(list.toArray(new Properties[list.size()])); } }
javaBean配置:
public class UserServiceImpl implements IUserService{ private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class); public UserServiceImpl(){ logger.info("UserServiceImpl 构造函数 "); } private String username; private String password; public String getUsername() { return username; } public String getPassword() { return password; } public void setUsername(String username) { logger.info("UserServiceImpl setUsername {}",username); this.username = username; } public void setPassword(String password) { logger.info("UserServiceImpl setPassword {}",password); this.password = password; } @Override public String toString() { return "UserServiceImpl [username=" + username + ", password=" + password + "]"; } }
测试:
public class TestApplicationContext { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext( "classpath:spring/applicationContext.xml"); IUserService userService = applicationContext.getBean(IUserService.class); String password = userService.getPassword(); applicationContext.destroy(); System.out.println(password); } }
------------------------------系统调用入口:------------------------------
调用入口: