BeanDefinitionVisitor, 遍歷bean的各個屬性用properties填充, BeanDefinitionVisitor會將替換的操作委托給內(nèi)部的一個StringValueResolver來執(zhí)行(PlaceholderResolvingStringValueResolver), 而這個StringValueResolver又會將操作委托給PropertyPlaceholderHelper, 這個helper(PropertyPlaceholderHelper)在實際執(zhí)行的時候會執(zhí)行內(nèi)部的parseStringValue函數(shù)
使用BeanDefinitionVisitor的visitBeanDefinition方法來解析
protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
StringValueResolver valueResolver) {
BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);
String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
for (String curName : beanNames) {
// Check that we're not parsing our own bean definition,
// to avoid failing on unresolvable placeholders in properties file locations.
if (!(curName.equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) {
BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(curName);
try {
visitor.visitBeanDefinition(bd);
}
catch (Exception ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), curName, ex.getMessage(), ex);
}
}
}
// New in Spring 2.5: resolve placeholders in alias target names and aliases as well.
beanFactoryToProcess.resolveAliases(valueResolver);
// New in Spring 3.0: resolve placeholders in embedded values such as annotation attributes.
beanFactoryToProcess.addEmbeddedValueResolver(valueResolver);
}
解析之后BeanDefinition的占位符將會被替換掉
image.png
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 valueResolver = new StringValueResolver(){
public String resolveStringValue(String strVal){
if(isObscene(StrVal)) return "******";
return strVal;
}
}
BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);
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 obscenty : obscenties){
this.obscenties.add(obscenty.toUpperCase());
}
}
}