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

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



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • IoC 容器 Bean 的作用域 自定義作用域?qū)崿F(xiàn) org.springframework.beans.facto...
    Hsinwong閱讀 2,502評論 0 7
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,833評論 0 11
  • 小編費力收集:給你想要的面試集合 1.C++或Java中的異常處理機制的簡單原理和應用。 當JAVA程序違反了JA...
    八爺君閱讀 4,650評論 1 114
  • JAVA面試題 1、作用域public,private,protected,以及不寫時的區(qū)別答:區(qū)別如下:作用域 ...
    JA尐白閱讀 1,182評論 1 0
  • 1.import static是Java 5增加的功能,就是將Import類中的靜態(tài)方法,可以作為本類的靜態(tài)方法來...
    XLsn0w閱讀 1,262評論 0 2