Spring之beanFactory

Spring本身就是一个容器(工厂),里面放的是Spring初始化的bean,我们只需从中取相应的bean就可以了,BeanFactory就是访问Spring bean容器的根接口(root interface),该接口定义了如下几个方法:

Object getBean(String name) throws BeansException;
getBean方法:返回指定bean的实例,该实例可以是共享的或独立的。Spring BeanFactory可以被用作Singleton或Prototype设计模式的替代。 在Singleton bean的情况下,调用者可以保留对返回对象的引用。将别名转换回相应的规范bean名称。如果在此工厂实例中找不到bean 将询问父工厂。

boolean containsBean(String name);
containsBean方法:如果给定的名称是别名,则它将被转换回相应的规范bean名称。如果找到与给定名称匹配bean的定义或单例实例,则此方法将返回true

boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
isSingleton方法:判断该bean是否是共享的单例,注意:此方法返回false并不能清楚地指示独立实例。 它表示非单例实例,也可以对应于作用域bean。 使用isPrototype操作显式检查独立实例。

boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
isPrototype:判断该bean是否是原型,注意:此方法返回false并不能清楚地指示单个对象。 它表示非独立实例,也可以对应于范围bean。 使用isSingleton操作显式检查共享单例实例。

boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
isTypeMatch方法:检查给定名称的bean是否与指定的类型匹配。 即检查给定名称的getBean调用是否将返回可分配给指定目标类型的对象。

Class<?> getType(String name) throws NoSuchBeanDefinitionException;
getType方法:确定给定名称的bean的类型。 即确定getBean为给定名称返回的对象类型。对于FactoryBean返回FactoryBean创建的对象类型。由FactoryBean.getObjectType方法实现

String[] getAliases(String name);
getAliases方法:返回给定bean名称的别名(如果有)。 当在getBean调用中使用时所有这些别名都指向同一个bean。

ListableBeanFactory也是一个接口,该接口继承了beanFactory接口,该接口定义了如下几个方法:

boolean containsBeanDefinition(String beanName);
containsBeanDefinition方法:判断传入的beanName是否在bean factroy中被定义。

int getBeanDefinitionCount();
getBeanDefinitionCount方法:返回bean factory中的定义定义了的bean的个数。

String[] getBeanDefinitionNames();
getBeanDefinitionNames方法:返回bean factory中定义了的bean的名字。

String[] getBeanNamesForType(ResolvableType type);
getBeanNamesForType方法:返回与传入的类型(type)(包括子类)匹配的bean的名称,从bean定义或FactoryBeans的getObjectType值判断。

String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
getBeanNamesForAnnotation方法:返回bean中提供Annotation类型的的所有名称,不创建任何bean实例。

Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
getBeansWithAnnotation:同上,只是返回类型不同

<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
            throws NoSuchBeanDefinitionException;
findAnnotationOnBean方法:在指定的bean上查找annotationType的注释(Annotation),如果在给定的类本身上找不到注释,则遍历实现的接口和继承的父类。

ConfigurableListableBeanFactory继承了ListableBeanFactory,和AutowireCapableBeanFactory, ConfigurableBeanFactory 三个接口,接口ConfigurableListableBeanFactory定义了如下的方法:

void ignoreDependencyType(Class<?> type);
ignoreDependencyType方法:忽略自动装配的依赖类型,举个例子,String类型忽略后就是none。

void ignoreDependencyInterface(Class<?> ifc);
ignoreDependencyInterface方法:忽略自动装配依赖关系的接口。

void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);
registerResolvableDependency方法:注册一个特殊的依赖关系的自动注入。

boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
            throws NoSuchBeanDefinitionException;
isAutowireCandidate方法:判断指定的bean是否可以作为autowire候选者,并将其注入到与之匹配的依赖关系的bean中。

BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
getBeanDefinition方法:返回指定bean的已注册BeanDefinition,允许访问其属性值和构造函数参数值(可以在bean工厂后处理期间修改)。返回的BeanDefinition对象不应是副本,而应是在工厂中注册的原始定义对象。 这意味着如果需要,它应该可以转换为更具体的实现类型。

Iterator<String> getBeanNamesIterator();
getBeanNamesIterator方法:返回工厂管理的所有bean名称的统一视图。

void clearMetadataCache();
clearMetadataCache方法:清除合并的bean定义缓存,删除尚未被认为有资格进行完整元数据缓存的bean条目,通常在更改原始bean定义后触发,例如 在应用BeanFactoryPostProcessor之后,请注意,此时已创建的bean的元数据将保留。

void freezeConfiguration();
freezeConfiguration方法:冻结所有bean定义,表明注册的bean定义不会被修改或进一步后处理。

boolean isConfigurationFrozen();
isConfigurationFrozen方法:返回该工厂的bean定义是否被冻结,即不应该进一步修改或后处理。

void preInstantiateSingletons() throws BeansException;
preInstantiateSingletons方法:确保所有non-lazy-init单例都被实例化,同时考虑FactoryBeans, 如果需要,通常在出厂设置结束时调用。

DefaultListableBeanFactory类实现了ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable等接口,继承了AbstractAutowireCapableBeanFactory类。DefaultListableBeanFactory实现了如下几个方法:

// Implementation of remaining BeanFactory methods

1.T getBean(Class<T> requiredType) throws BeansException 

2.T getBean(Class<T> requiredType, Object... args) throws BeansException 

3.public <T> T getBean(Class<T> requiredType, Object... args)throws BeansException {
        NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);
        if (namedBean != null) {
                       //返回相应的bean实例(可以为null)。
            return namedBean.getBeanInstance();
        }
                //返回父类的bean工厂,如果没有则返回null
        BeanFactory parent = getParentBeanFactory();
        if (parent != null) {
                        //返回指定bean的实例,该实例可以是共享的或独立的。
            return parent.getBean(requiredType, args);
        }
        throw new NoSuchBeanDefinitionException(requiredType);
    }

// Implementation of ListableBeanFactory interface
1.boolean containsBeanDefinition(String beanName)

2.int getBeanDefinitionCount()

3.String[] getBeanDefinitionNames()

4.String[] getBeanNamesForType(ResolvableType type)

//
5.public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
        if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
            return doGetBeanNamesForType(ResolvableType.forRawClass(type),                                                  includeNonSingletons, allowEagerInit);
        }
        Map<Class<?>, String[]> cache =
                (includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
        String[] resolvedBeanNames = cache.get(type);
        if (resolvedBeanNames != null) {
            return resolvedBeanNames;
        }
        resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
        if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
            cache.put(type, resolvedBeanNames);
        }
        return resolvedBeanNames;
    }


6.private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
        List<String> result = new ArrayList<String>();

        //检查所有bean的定义
        for (String beanName : this.beanDefinitionNames) {
            // Only consider bean as eligible if the bean name
            // is not defined as alias for some other bean.
                        //如果bean名称未定义为其他bean的别名,那么他就是合格的
            if (!isAlias(beanName)) {
                try {
                    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                    // Only check bean definition if it is complete.
                    if (!mbd.isAbstract() && (allowEagerInit ||
                            ((mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading())) &&
                                    !requiresEagerInitForType(mbd.getFactoryBeanName()))) {
                        // In case of FactoryBean, match object created by FactoryBean.
                        boolean isFactoryBean = isFactoryBean(beanName, mbd);
                        BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
                        boolean matchFound =
                                (allowEagerInit || !isFactoryBean ||
                                        (dbd != null && !mbd.isLazyInit()) || containsSingleton(beanName)) &&
                                (includeNonSingletons ||
                                        (dbd != null ? mbd.isSingleton() : isSingleton(beanName))) &&
                                isTypeMatch(beanName, type);
                        if (!matchFound && isFactoryBean) {
                            // In case of FactoryBean, try to match FactoryBean instance itself next.
                            beanName = FACTORY_BEAN_PREFIX + beanName;
                            matchFound = (includeNonSingletons || mbd.isSingleton()) && isTypeMatch(beanName, type);
                        }
                        if (matchFound) {
                            result.add(beanName);
                        }
                    }
                }
                catch (CannotLoadBeanClassException ex) {
                    if (allowEagerInit) {
                        throw ex;
                    }
                    // Probably contains a placeholder: let's ignore it for type matching purposes.
                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug("Ignoring bean class loading failure for bean '" + beanName + "'", ex);
                    }
                    onSuppressedException(ex);
                }
                catch (BeanDefinitionStoreException ex) {
                    if (allowEagerInit) {
                        throw ex;
                    }
                    // Probably contains a placeholder: let's ignore it for type matching purposes.
                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug("Ignoring unresolvable metadata in bean definition '" + beanName + "'", ex);
                    }
                    onSuppressedException(ex);
                }
            }
        }

        // Check manually registered singletons too.
        for (String beanName : this.manualSingletonNames) {
            try {
                // In case of FactoryBean, match object created by FactoryBean.
                if (isFactoryBean(beanName)) {
                    if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
                        result.add(beanName);
                        // Match found for this bean: do not match FactoryBean itself anymore.
                        continue;
                    }
                    // In case of FactoryBean, try to match FactoryBean itself next.
                    beanName = FACTORY_BEAN_PREFIX + beanName;
                }
                // Match raw bean instance (might be raw FactoryBean).
                if (isTypeMatch(beanName, type)) {
                    result.add(beanName);
                }
            }
            catch (NoSuchBeanDefinitionException ex) {
                // Shouldn't happen - probably a result of circular reference resolution...
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to check manually registered singleton with name '" + beanName + "'", ex);
                }
            }
        }

        return StringUtils.toStringArray(result);
    }



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容

  • 2.1 我们的理念是:让别人为你服务 IoC是随着近年来轻量级容器(Lightweight Container)的...
    好好学习Sun阅读 2,698评论 0 11
  • 本文是我自己在秋招复习时的读书笔记,整理的知识点,也是为了防止忘记,尊重劳动成果,转载注明出处哦!如果你也喜欢,那...
    波波波先森阅读 12,272评论 6 86
  • 本来是准备看一看Spring源码的。然后在知乎上看到来一个帖子,说有一群**自己连Spring官方文档都没有完全读...
    此鱼不得水阅读 6,925评论 4 21
  • Spring容器高层视图 Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相...
    Theriseof阅读 2,794评论 1 24
  • 关于生活(二) 所述内容仅为个人观点和生活习性。你可以不认同,不喜欢甚至厌恶鄙视,但还请保持克制,...
    就怕不够浪阅读 462评论 0 1