DefaultListableBeanFactory

来源:互联网 发布:java暑期培训班 编辑:程序博客网 时间:2024/06/13 20:13

DefaultListableBeanFactory是整个bean加载的核心部分,是Spring注册机加载bean的默认实现。UML结构图如下:
DefaultListableBeanFactory
根据上图的结构关系图,各个类的简单描述如下:

 1.  AliasRegistry:定义对alias的简单增删查改操作
//别名管理public interface AliasRegistry {    //注册给定类名的别名    void registerAlias(String name, String alias);    //删除特定别名的注册信息    void removeAlias(String alias);    //判断给定的名字是否是别名    boolean isAlias(String name);    //返回特定bean name的别名    String[] getAliases(String name)}
 2. SimpleAliasRegistry:主要使用map作为alias的缓存,并实现AliasRegistry接口
public class SimpleAliasRegistry implements AliasRegistry {    //别名和类名之间的映射关系,使用ConcurrentHashMap是线程安全的    private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16);    /**     * 实现AliasRegistry的注册方法     * 1、对name和alias进行校验     * 2、如果别名和名字相同则从ConcurrentHashMap中删除别名,否则到3     * 3、获取alias对应的bean name,如果已经注册的名字和类名相同,则直接返回     * 4、如果alias对应的类名不等于现在要注册的bean name,并且允许重写,则将原来注册的进行替换,为当前的映射关系     * 5、checkForAliasCircle用来判断是否存在alias和bean name循环映射的关系     * 6、以上没问题则将映射关系添加进map     */    @Override    public void registerAlias(String name, String alias) {        Assert.hasText(name, "'name' must not be empty");        Assert.hasText(alias, "'alias' must not be empty");        if (alias.equals(name)) {            this.aliasMap.remove(alias);        }        else {            String registeredName = this.aliasMap.get(alias);            if (registeredName != null) {                if (registeredName.equals(name)) {                    // An existing alias - no need to re-register                    return;                }                if (!allowAliasOverriding()) {                    throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" +                            name + "': It is already registered for name '" + registeredName + "'.");                }            }            checkForAliasCircle(name, alias);            this.aliasMap.put(alias, name);        }    }    //是否允许对原来有相同alias的映射关系进行重写,如果允许则覆盖旧的映射关系    protected boolean allowAliasOverriding() {        return true;    }     //判断当前类名的alias是否已经注册,注意此时可能存在循环映射,可以看成一个树     //类似这种结构alias -> ... -> registeredAlias -> name    public boolean hasAlias(String name, String alias) {        for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) {            String registeredName = entry.getValue();            if (registeredName.equals(name)) {                String registeredAlias = entry.getKey();                return (registeredAlias.equals(alias) || hasAlias(registeredAlias, alias));            }        }        return false;    }    //删除映射关系    @Override    public void removeAlias(String alias) {        String name = this.aliasMap.remove(alias);        if (name == null) {            throw new IllegalStateException("No alias '" + alias + "' registered");        }    }    //判断alias表里面是否存在和name相同的alias    @Override    public boolean isAlias(String name) {        return this.aliasMap.containsKey(name);    }    //获取bean name的所有别名    @Override    public String[] getAliases(String name) {        List<String> result = new ArrayList<String>();        synchronized (this.aliasMap) {            retrieveAliases(name, result);        }        return StringUtils.toStringArray(result);    }    //获取bean name的所有别名过程函数,递归的查找,可以理解成树形结构    private void retrieveAliases(String name, List<String> result) {        for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) {            String registeredName = entry.getValue();            if (registeredName.equals(name)) {                String alias = entry.getKey();                result.add(alias);                retrieveAliases(alias, result);            }        }    }    //处理所有的别名,如果处理正确,把原来的用解析后的替换,ValueResolver 解析器    public void resolveAliases(StringValueResolver valueResolver) {        Assert.notNull(valueResolver, "StringValueResolver must not be null");        synchronized (this.aliasMap) {            Map<String, String> aliasCopy = new HashMap<String, String>(this.aliasMap);            for (String alias : aliasCopy.keySet()) {                String registeredName = aliasCopy.get(alias);                String resolvedAlias = valueResolver.resolveStringValue(alias);                String resolvedName = valueResolver.resolveStringValue(registeredName);                if (resolvedAlias == null || resolvedName == null || resolvedAlias.equals(resolvedName)) {                    this.aliasMap.remove(alias);                }                else if (!resolvedAlias.equals(alias)) {                    String existingName = this.aliasMap.get(resolvedAlias);                    if (existingName != null) {                        if (existingName.equals(resolvedName)) {                            // Pointing to existing alias - just remove placeholder                            this.aliasMap.remove(alias);                            break;                        }                        throw new IllegalStateException(                                "Cannot register resolved alias '" + resolvedAlias + "' (original: '" + alias +                                "') for name '" + resolvedName + "': It is already registered for name '" +                                registeredName + "'.");                    }                    checkForAliasCircle(resolvedName, resolvedAlias);                    this.aliasMap.remove(alias);                    this.aliasMap.put(resolvedAlias, resolvedName);                }                else if (!registeredName.equals(resolvedName)) {                    this.aliasMap.put(alias, resolvedName);                }            }        }    }    //判断是否存在循环映射    protected void checkForAliasCircle(String name, String alias) {        if (hasAlias(alias, name)) {            throw new IllegalStateException("Cannot register alias '" + alias +                    "' for name '" + name + "': Circular reference - '" +                    name + "' is a direct or indirect alias for '" + alias + "' already");        }    }    //找到bean真实名字的方法就是根据层层的别名关系,直到找出这样一个名字,这个名字在aliasMap中作为别名已经找不到对应的真实bean名字,也就是说这个名字已经不是别名就是bean的名字    public String canonicalName(String name) {        String canonicalName = name;        // Handle aliasing...        String resolvedName;        do {            resolvedName = this.aliasMap.get(canonicalName);            if (resolvedName != null) {                canonicalName = resolvedName;            }        }        while (resolvedName != null);        return canonicalName;    }}
3.  SingletonBeanRegistry:定义对单例的注册及获取
public interface SingletonBeanRegistry {    //在bean注册器里面注册beanName对应的单例bean    void registerSingleton(String beanName, Object singletonObject);    //返回注册名字对应的实例    Object getSingleton(String beanName);    //检查给定的beanName是否已经注册    boolean containsSingleton(String beanName);    //返回已经注册的所有单例的名字    String[] getSingletonNames();    //返回已经注册的单例个数    int getSingletonCount();    //返回互斥量    Object getSingletonMutex();}
4. BeanFactory:定义获取bean及bean的各种属性
public interface BeanFactory {    //指定factoryBean的前缀,Bean工厂里面的实例任然有可能是一个BeanFactory,如果是个BeanFactory    //则可以通过如下方法返回一个BeanFactory,factory.getBean("&beanfactoryName");    String FACTORY_BEAN_PREFIX = "&";    //返回特定名字的实例    Object getBean(String name) throws BeansException;    //返回特定名称及特定类型的实例    <T> T getBean(String name, Class<T> requiredType) throws BeansException;     //返回特定类型的bean实例,如果不存在或存在不止一个均报错    <T> T getBean(Class<T> requiredType) throws BeansException;     //根据名字及bean创建时候的参数创建bean    Object getBean(String name, Object... args) throws BeansException;    //根据特定的construct args创建prototype的bean    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;    //判断是否包含特定名字的实例    boolean containsBean(String name);    //判断是否是单例的    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;    //判断是否是多例的    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;    //判断特定名字的实例和对应的type是否匹配    boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;    //判断特定名字的实例和对应的type是否匹配    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;    //返回特定名称bean的类型    Class<?> getType(String name) throws NoSuchBeanDefinitionException;    //返回特定name bean的别名    String[] getAliases(String name);}
5. DefautlSingletonBeanRegistry:对SingleBeanRegistry的实现
0 0
原创粉丝点击