设计模式课程 设计模式精讲 26-3 访问者模式源码解析

1    源码解析

1.1    源码解析1(jdk文件访问者的应用

1.2    源码解析2(Spring中bean访问者的应用)

 

 

 

 

1    源码解析
1.1    源码解析1(jdk文件访问者的应用)
功能:

1  通过FileVisitor遍历文件数比较方便,比如文件夹内查找符合条件的文件,或者 按时间查找某一天创建的文件。

2  由于实现类只有一个,如果实现类不能满足我们的要求,我们可以继承实现类重写方法,或者实现fileVisitor接口,自己写方法。

接口FileVisitor:

package java.nio.file;

import java.io.IOException;
import java.nio.file.attribute.BasicFileAttributes;

public interface FileVisitor<T> {
    FileVisitResult preVisitDirectory(T var1, BasicFileAttributes var2) throws IOException;

    FileVisitResult visitFile(T var1, BasicFileAttributes var2) throws IOException;

    FileVisitResult visitFileFailed(T var1, IOException var2) throws IOException;

    FileVisitResult postVisitDirectory(T var1, IOException var2) throws IOException;
}

 实现类:

package java.nio.file;

import java.nio.file.attribute.BasicFileAttributes;
import java.io.IOException;
import java.util.Objects;



public class SimpleFileVisitor<T> implements FileVisitor<T> {
    /**
     * Initializes a new instance of this class.
     */
    protected SimpleFileVisitor() {
    }


    @Override
    public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
        throws IOException
    {
        Objects.requireNonNull(dir);
        Objects.requireNonNull(attrs);
        return FileVisitResult.CONTINUE;
    }


    @Override
    public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
        throws IOException
    {
        Objects.requireNonNull(file);
        Objects.requireNonNull(attrs);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(T file, IOException exc)
        throws IOException
    {
        Objects.requireNonNull(file);
        throw exc;
    }

    @Override
    public FileVisitResult postVisitDirectory(T dir, IOException exc)
        throws IOException
    {
        Objects.requireNonNull(dir);
        if (exc != null)
            throw exc;
        return FileVisitResult.CONTINUE;
    }
}
1.2    源码解析2(Spring中bean访问者的应用)

BeanDefinitionVisitor(可以遍历bean的属性,用properties来进行填充。构造器的时候委托StringValueResolver(this.resolveStringValue) 来实现

SpringIOC要求比较复杂,该类主要是分析bean的各种数据,然后把它们进行分解。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.beans.factory.config;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringValueResolver;

public class BeanDefinitionVisitor {
    private StringValueResolver valueResolver;

    public BeanDefinitionVisitor(StringValueResolver valueResolver) {
        Assert.notNull(valueResolver, "StringValueResolver must not be null");
        this.valueResolver = valueResolver;
    }

    protected BeanDefinitionVisitor() {
    }

    public void visitBeanDefinition(BeanDefinition beanDefinition) {
        this.visitParentName(beanDefinition);
        this.visitBeanClassName(beanDefinition);
        this.visitFactoryBeanName(beanDefinition);
        this.visitFactoryMethodName(beanDefinition);
        this.visitScope(beanDefinition);
        this.visitPropertyValues(beanDefinition.getPropertyValues());
        ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues();
        this.visitIndexedArgumentValues(cas.getIndexedArgumentValues());
        this.visitGenericArgumentValues(cas.getGenericArgumentValues());
    }

    protected void visitParentName(BeanDefinition beanDefinition) {
        String parentName = beanDefinition.getParentName();
        if (parentName != null) {
            String resolvedName = this.resolveStringValue(parentName);
            if (!parentName.equals(resolvedName)) {
                beanDefinition.setParentName(resolvedName);
            }
        }

    }

    protected void visitBeanClassName(BeanDefinition beanDefinition) {
        String beanClassName = beanDefinition.getBeanClassName();
        if (beanClassName != null) {
            String resolvedName = this.resolveStringValue(beanClassName);
            if (!beanClassName.equals(resolvedName)) {
                beanDefinition.setBeanClassName(resolvedName);
            }
        }

    }

    protected void visitFactoryBeanName(BeanDefinition beanDefinition) {
        String factoryBeanName = beanDefinition.getFactoryBeanName();
        if (factoryBeanName != null) {
            String resolvedName = this.resolveStringValue(factoryBeanName);
            if (!factoryBeanName.equals(resolvedName)) {
                beanDefinition.setFactoryBeanName(resolvedName);
            }
        }

    }

    protected void visitFactoryMethodName(BeanDefinition beanDefinition) {
        String factoryMethodName = beanDefinition.getFactoryMethodName();
        if (factoryMethodName != null) {
            String resolvedName = this.resolveStringValue(factoryMethodName);
            if (!factoryMethodName.equals(resolvedName)) {
                beanDefinition.setFactoryMethodName(resolvedName);
            }
        }

    }

    protected void visitScope(BeanDefinition beanDefinition) {
        String scope = beanDefinition.getScope();
        if (scope != null) {
            String resolvedScope = this.resolveStringValue(scope);
            if (!scope.equals(resolvedScope)) {
                beanDefinition.setScope(resolvedScope);
            }
        }

    }

    protected void visitPropertyValues(MutablePropertyValues pvs) {
        PropertyValue[] pvArray = pvs.getPropertyValues();
        PropertyValue[] var3 = pvArray;
        int var4 = pvArray.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            PropertyValue pv = var3[var5];
            Object newVal = this.resolveValue(pv.getValue());
            if (!ObjectUtils.nullSafeEquals(newVal, pv.getValue())) {
                pvs.add(pv.getName(), newVal);
            }
        }

    }

    protected void visitIndexedArgumentValues(Map<Integer, ValueHolder> ias) {
        Iterator var2 = ias.values().iterator();

        while(var2.hasNext()) {
            ValueHolder valueHolder = (ValueHolder)var2.next();
            Object newVal = this.resolveValue(valueHolder.getValue());
            if (!ObjectUtils.nullSafeEquals(newVal, valueHolder.getValue())) {
                valueHolder.setValue(newVal);
            }
        }

    }

    protected void visitGenericArgumentValues(List<ValueHolder> gas) {
        Iterator var2 = gas.iterator();

        while(var2.hasNext()) {
            ValueHolder valueHolder = (ValueHolder)var2.next();
            Object newVal = this.resolveValue(valueHolder.getValue());
            if (!ObjectUtils.nullSafeEquals(newVal, valueHolder.getValue())) {
                valueHolder.setValue(newVal);
            }
        }

    }

    protected Object resolveValue(Object value) {
        if (value instanceof BeanDefinition) {
            this.visitBeanDefinition((BeanDefinition)value);
        } else if (value instanceof BeanDefinitionHolder) {
            this.visitBeanDefinition(((BeanDefinitionHolder)value).getBeanDefinition());
        } else {
            String stringValue;
            if (value instanceof RuntimeBeanReference) {
                RuntimeBeanReference ref = (RuntimeBeanReference)value;
                stringValue = this.resolveStringValue(ref.getBeanName());
                if (!stringValue.equals(ref.getBeanName())) {
                    return new RuntimeBeanReference(stringValue);
                }
            } else if (value instanceof RuntimeBeanNameReference) {
                RuntimeBeanNameReference ref = (RuntimeBeanNameReference)value;
                stringValue = this.resolveStringValue(ref.getBeanName());
                if (!stringValue.equals(ref.getBeanName())) {
                    return new RuntimeBeanNameReference(stringValue);
                }
            } else if (value instanceof Object[]) {
                this.visitArray((Object[])((Object[])value));
            } else if (value instanceof List) {
                this.visitList((List)value);
            } else if (value instanceof Set) {
                this.visitSet((Set)value);
            } else if (value instanceof Map) {
                this.visitMap((Map)value);
            } else if (value instanceof TypedStringValue) {
                TypedStringValue typedStringValue = (TypedStringValue)value;
                stringValue = typedStringValue.getValue();
                if (stringValue != null) {
                    String visitedString = this.resolveStringValue(stringValue);
                    typedStringValue.setValue(visitedString);
                }
            } else if (value instanceof String) {
                return this.resolveStringValue((String)value);
            }
        }

        return value;
    }

    protected void visitArray(Object[] arrayVal) {
        for(int i = 0; i < arrayVal.length; ++i) {
            Object elem = arrayVal[i];
            Object newVal = this.resolveValue(elem);
            if (!ObjectUtils.nullSafeEquals(newVal, elem)) {
                arrayVal[i] = newVal;
            }
        }

    }

    protected void visitList(List listVal) {
        for(int i = 0; i < listVal.size(); ++i) {
            Object elem = listVal.get(i);
            Object newVal = this.resolveValue(elem);
            if (!ObjectUtils.nullSafeEquals(newVal, elem)) {
                listVal.set(i, newVal);
            }
        }

    }

    protected void visitSet(Set setVal) {
        Set newContent = new LinkedHashSet();
        boolean entriesModified = false;

        Object elem;
        int elemHash;
        Object newVal;
        int newValHash;
        for(Iterator var4 = setVal.iterator(); var4.hasNext(); entriesModified = entriesModified || newVal != elem || newValHash != elemHash) {
            elem = var4.next();
            elemHash = elem != null ? elem.hashCode() : 0;
            newVal = this.resolveValue(elem);
            newValHash = newVal != null ? newVal.hashCode() : 0;
            newContent.add(newVal);
        }

        if (entriesModified) {
            setVal.clear();
            setVal.addAll(newContent);
        }

    }

    protected void visitMap(Map<?, ?> mapVal) {
        Map newContent = new LinkedHashMap();
        boolean entriesModified = false;

        Object key;
        int keyHash;
        Object newKey;
        int newKeyHash;
        Object val;
        Object newVal;
        for(Iterator var4 = mapVal.entrySet().iterator(); var4.hasNext(); entriesModified = entriesModified || newVal != val || newKey != key || newKeyHash != keyHash) {
            Entry entry = (Entry)var4.next();
            key = entry.getKey();
            keyHash = key != null ? key.hashCode() : 0;
            newKey = this.resolveValue(key);
            newKeyHash = newKey != null ? newKey.hashCode() : 0;
            val = entry.getValue();
            newVal = this.resolveValue(val);
            newContent.put(newKey, newVal);
        }

        if (entriesModified) {
            mapVal.clear();
            mapVal.putAll(newContent);
        }

    }

    protected String resolveStringValue(String strVal) {
        if (this.valueResolver == null) {
            throw new IllegalStateException("No StringValueResolver specified - pass a resolver object into the constructor or override the 'resolveStringValue' method");
        } else {
            String resolvedValue = this.valueResolver.resolveStringValue(strVal);
            return strVal.equals(resolvedValue) ? strVal : resolvedValue;
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/1446358788-qq/p/12433705.html