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; } }