Spring容器深度扩展——postProcessBeanFactory之BeanDefinitionVisitor

BeanDefinitionVisitor, 遍历bean的各个属性用properties填充, BeanDefinitionVisitor会将替换的操作委托给内部的一个StringValueResolver来执行(PlaceholderResolvingStringValueResolver), 而这个StringValueResolver又会将操作委托给PropertyPlaceholderHelper, 这个helper(PropertyPlaceholderHelper)在实际执行的时候会执行内部的parseStringValue函数

使用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 obscenties;
    public ObscenityRemovingBeanFactoryPostProcessor(){
        this.obscenties = new HashSet();
    }
 
    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 obscenties){
        this.obscenties.clear();
        for(String obscenty : obscenties){
            this.obscenties.add(obscenty.toUpperCase());
        }
    }
}



你可能感兴趣的:(Spring容器深度扩展——postProcessBeanFactory之BeanDefinitionVisitor)