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



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • IoC 容器 Bean 的作用域 自定义作用域实现 org.springframework.beans.facto...
    Hsinwong阅读 2,502评论 0 7
  • 一. Java基础部分.................................................
    wy_sure阅读 3,833评论 0 11
  • 小编费力收集:给你想要的面试集合 1.C++或Java中的异常处理机制的简单原理和应用。 当JAVA程序违反了JA...
    八爷君阅读 4,650评论 1 114
  • JAVA面试题 1、作用域public,private,protected,以及不写时的区别答:区别如下:作用域 ...
    JA尐白阅读 1,182评论 1 0
  • 1.import static是Java 5增加的功能,就是将Import类中的静态方法,可以作为本类的静态方法来...
    XLsn0w阅读 1,262评论 0 2