package com.spring.ch04;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class PropertyConfigurerDemo {
public static void main(String[] args) {
ConfigurableListableBeanFactory bf=new XmlBeanFactory(new ClassPathResource("/META-INF/postprocessor.xml"));
BeanFactoryPostProcessor bfpp=(BeanFactoryPostProcessor)bf.getBean("bfpp");
bfpp.postProcessBeanFactory(bf);
System.out.println(bf.getBean("simpleBean"));
}
}
BeanFactory配置文件:postprocessor.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
">
<!-- 利用PropertyPlaceholderConfigurer回调处理器将替换从已配置的属性文件中加载属性的值,
只要值符合某种格式规则,默认情况下是${property-name},就会发生替换。
-->
<bean id="bfpp" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:/META-INF/bfpp.properties"></property>
</bean>
<bean id="simpleBean" class="com.spring.ch04.SimplePostProcessor">
<property name="connectionString" value="${simpleBean.connectionString}"/>
<property name="password" value="${simpleBean.password}"/>
<property name="username" value="${simpleBean.username}"/>
</bean>
</beans>
SimplePostProcessor .java
package com.spring.ch04;
public class SimplePostProcessor {
private String connectionString;
private String password;
private String username;
public void setConnectionString(String connectionString) {
this.connectionString = connectionString;
}
public void setPassword(String password) {
this.password = password;
}
public void setUsername(String username) {
this.username = username;
}
public String toString(){
StringBuilder sb=new StringBuilder();
sb.append("SimplePostProcessor{connectionString=").append(this.connectionString);
sb.append(",username=").append(this.username).append(",password=").append(this.password);
return sb.toString();
}
}
bfpp.properties
simpleBean.connectionString=Hello
simpleBean.password=imaginecup
simpleBean.username=qiaoyanhui
实现一个BeanFactoryPostProcessor,实现一个简单的回调处理器,它能去除潜在的"流氓"属性值,例如bean定义中留下bollocks这样的字眼。
配置文件:BeanFactory.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean id="bfpp" class="com.spring.ch04.ObscenityRemovingBeanFactoryPostProcessor">
<property name="obscenties">
<set>
<value>bollocks</value>
<value>winky</value>
<value>bum</value>
<value>Microsoft</value>
</set>
</property>
</bean>
<bean id="simpleBean" class="com.spring.ch04.SimplePostProcessor">
<property name="connectionString" value="bollocks"/>
<property name="password" value="imaginecup"/>
<property name="username" value="Microsoft"/>
</bean>
</beans>
ObscenityRemovingBeanFactoryPostProcessor.java
package com.spring.ch04;
import java.util.*;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionVisitor;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.util.StringValueResolver;
public class ObscenityRemovingBeanFactoryPostProcessor implements
BeanFactoryPostProcessor {
private Set<String> obscenties;
public ObscenityRemovingBeanFactoryPostProcessor(){
this.obscenties=new HashSet<String>();
}
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanNames=beanFactory.getBeanDefinitionNames();
for(String beanName:beanNames){
BeanDefinition bd=beanFactory.getBeanDefinition(beanName);
StringValueResolver valueResover=new StringValueResolver() {
public String resolveStringValue(String strVal) {
if(isObscene(strVal)) return "*****";
return strVal;
}
};
BeanDefinitionVisitor visitor=new BeanDefinitionVisitor(valueResover);
visitor.visitBeanDefinition(bd);
}
}
public boolean isObscene(Object value){
String potentialObscenity=value.toString().toUpperCase();
return this.obscenties.contains(potentialObscenity);
}
public void setObscenties(Set<String> obscenties) {
this.obscenties.clear();
for(String obscenity:obscenties){
this.obscenties.add(obscenity.toUpperCase());
}
}
}
执行类:
package com.spring.ch04;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class PropertyConfigurerDemo {
public static void main(String[] args) {
ConfigurableListableBeanFactory bf=new XmlBeanFactory(new ClassPathResource("/META-INF/BeanFactory.xml"));
BeanFactoryPostProcessor bfpp=(BeanFactoryPostProcessor)bf.getBean("bfpp");
bfpp.postProcessBeanFactory(bf);
System.out.println(bf.getBean("simpleBean"));
}
}
输出结果:
SimplePostProcessor{connectionString=*****,username=*****,password=imaginecup
ObscenityRemovingBeanFactoryPostProcessor.java的改进类
ObscenityRemovingBeanFactoryPostProcessor1.java
package com.spring.ch04;
import java.util.*;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionVisitor;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.util.StringValueResolver;
public class ObscenityRemovingBeanFactoryPostProcessor1 implements
BeanFactoryPostProcessor, BeanNameAware {
private Set<String> obscenities;
public ObscenityRemovingBeanFactoryPostProcessor1(){
this.obscenities=new HashSet<String>();
this.obscenitiesRemoved=new HashSet<String>();
}
public void setObscenities(Set<String> obscenities) {
this.obscenities.clear();
for(String obscenity :obscenities){
this.obscenities.add(obscenity.toUpperCase());
}
}
private Set<String> obscenitiesRemoved;
private String name;
@Override
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanNames=beanFactory.getBeanDefinitionNames();
for(String beanName:beanNames){
//核查我们有没有为该bean修改BeanDefinition
if(beanName.equals(this.name)) {
continue;
}
BeanDefinition bd=beanFactory.getBeanDefinition(beanName);
StringValueResolver valueResolver=new StringValueResolver(){
@Override
public String resolveStringValue(String strVal) {
if(isObscene(strVal)) {
obscenitiesRemoved.add(strVal);
return "******";
}
return strVal;
}
};
BeanDefinitionVisitor visitor=new BeanDefinitionVisitor(valueResolver);
visitor.visitBeanDefinition(bd);
}
//将一个集合注册名 为obscenitiesRemoved的单例bean
beanFactory.registerSingleton("obscenitiesRemoved", this.obscenitiesRemoved);
//打印被过滤的属性值
System.out.println(obscenitiesRemoved);
}
public boolean isObscene(Object obj){
String potentialObscenity=obj.toString().toUpperCase();
return this.obscenities.contains(potentialObscenity);
}
public void setBeanName(String name) {
this.name=name;
}
}