成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

重拾-Spring-IOC

GraphQuery / 3146人閱讀

摘要:為何重拾使用了多年,但是對(duì)其底層的一些實(shí)現(xiàn)還是一知半解,一些概念比較模糊故決定重新拾起,加深對(duì)的認(rèn)識(shí)。小結(jié)是在完成創(chuàng)建后對(duì)其進(jìn)行后置處理的接口是在完成實(shí)例化對(duì)其進(jìn)行的后置處理接口是框架底層的核心接口,其提供了創(chuàng)建,獲取等核心功能。

為何重拾

使用了 Spring 多年,但是對(duì)其底層的一些實(shí)現(xiàn)還是一知半解,一些概念比較模糊;故決定重新拾起,加深對(duì) Spring 的認(rèn)識(shí)。

重拾計(jì)劃 spring 版本說明

Spring 在經(jīng)過多年的演進(jìn)過程中,其功能越來越豐富,組件越來越多;為了避免在閱讀源碼的過程中深陷泥潭中,決定采用最原始的版本 1.0; 但又不局限于 1.0 版本。

spring ioc spring aop spring 事務(wù)管理 spring orm 集成 實(shí)現(xiàn)分析 Spring 容器啟動(dòng)
在本文中,通過常用的構(gòu)造 ClassPathXmlApplicationContext 實(shí)例來作為對(duì) Spring 實(shí)現(xiàn)分析的入口
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

通過調(diào)用鏈追蹤,Spring 容器啟動(dòng)核心操作由 AbstractApplicationContext 類中 refresh 方法實(shí)現(xiàn)

public void refresh() throws BeansException {
    this.startupTime = System.currentTimeMillis();

    // tell subclass to refresh the internal bean factory
    // 完成 xml 配置文件的解析, 解析 bean 標(biāo)簽生成 BeanDefinition 對(duì)象,并注冊(cè)到 BeanFactory
    refreshBeanFactory();
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();

    // configure the bean factory with context semantics
    beanFactory.registerCustomEditor(Resource.class, new ContextResourceEditor(this));
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    beanFactory.ignoreDependencyType(ResourceLoader.class);
    beanFactory.ignoreDependencyType(ApplicationContext.class);
    postProcessBeanFactory(beanFactory);

    // invoke factory processors registered with the context instance
    // 獲取內(nèi)置 BeanFactoryPostProcessor 實(shí)例,并遍歷調(diào)用 postProcessBeanFactory 方法
    // 對(duì) BeanFactory 進(jìn)行后置處理
    for (Iterator it = getBeanFactoryPostProcessors().iterator(); it.hasNext();) {
        BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next();
        factoryProcessor.postProcessBeanFactory(beanFactory);
    }

    if (getBeanDefinitionCount() == 0) {
        logger.warn("No beans defined in ApplicationContext [" + getDisplayName() + "]");
    }
    else {
        logger.info(getBeanDefinitionCount() + " beans defined in ApplicationContext [" + getDisplayName() + "]");
    }

    // invoke factory processors registered as beans in the context
    // 從 Bean Definition 集合中查找 BeanFactoryPostProcessor 定義并實(shí)例化
    // 獲取 BeanFactoryPostProcessor 實(shí)例,并遍歷調(diào)用 postProcessBeanFactory 方法
    // 對(duì) BeanFactory 進(jìn)行后置處理
    invokeBeanFactoryPostProcessors();

    // register bean processor that intercept bean creation
    // 從 Bean Definition 集合中查找 BeanPostProcessor 類定義實(shí)例化并注冊(cè)到 BeanFactory 中
    registerBeanPostProcessors();

    // initialize message source for this context
    initMessageSource();

    // initialize other special beans in specific context subclasses
    onRefresh();

    // check for listener beans and register them
    refreshListeners();

    // instantiate singletons this late to allow them to access the message source
    // 對(duì) Bean Definition 中單例且非延遲加載的類型進(jìn)行實(shí)例化
    /**
     * bean 初始化過程如下:
     * 1 : bean 構(gòu)造初始化
     * 2 : bean 屬性注入 (通過 bean definition 中的 property , autowire(byType, byName) 實(shí)現(xiàn))
     * 3 : bean 若實(shí)現(xiàn) BeanNameAware 接口,調(diào)用 setBeanName() 方法
     * 4 : bean 若實(shí)現(xiàn) BeanFactoryAware 接口, 調(diào)用 setBeanFactory() 方法
     * 5 : 遍歷調(diào)用 BeanFactory 中注冊(cè)的 BeanPostProcessor 實(shí)例的 postProcessorBeforeInitialization() 方法
     * 6 : bean 若實(shí)現(xiàn)了 InitializingBean 接口,調(diào)用 afterPropertiesSet() 方法
     * 7 : bean 實(shí)例對(duì)應(yīng)的 bean definition 中若定義了 init-method 屬性則調(diào)用對(duì)應(yīng)的 init 方法
     * 8 : 遍歷調(diào)用 BeanFactory 中注冊(cè)的 BeanPostProcessor 實(shí)例的 postProcessorAfterInitialization() 方法
     */
    beanFactory.preInstantiateSingletons();

    // last step: publish respective event
    publishEvent(new ContextRefreshedEvent(this));
}

從源碼中可知,Spring 容器在啟動(dòng)過程中,主要完成以下流程 :

通過加載指定的配置文件,完成 Bean Definition 解析并注冊(cè)到 BeanFactory 實(shí)例中

通過內(nèi)置及應(yīng)用自定義的 BeanFactoryPostProcessor 對(duì) BeanFactory 實(shí)例進(jìn)行后置處理

實(shí)例化應(yīng)用自定義的 BeanPostProcessor 并注冊(cè)到 BeanFactory 實(shí)例中

實(shí)例化 Spring 容器中的 Bean

Spring 容器關(guān)閉
public void close() {
    logger.info("Closing application context [" + getDisplayName() + "]");

    // destroy all cached singletons in this context,
    // invoking DisposableBean.destroy and/or "destroy-method"
    // 銷毀容器中緩存的單例對(duì)象實(shí)例
    // 執(zhí)行容器中 DisposableBean 的 destroy 方法
    getBeanFactory().destroySingletons();

    // publish respective event
    // 發(fā)送 spring 上下文關(guān)閉事件
    publishEvent(new ContextClosedEvent(this));
}

通過調(diào)用鏈追蹤,Spring 會(huì)遍歷容器中緩存的 bean 實(shí)例調(diào)用 destroyBean 方法。

protected void destroyBean(String beanName, Object bean) {
    logger.debug("Retrieving depending beans for bean "" + beanName + """);
    // 先銷毀所有依賴當(dāng)前 bean 的實(shí)例
    String[] dependingBeans = getDependingBeanNames(beanName);
    if (dependingBeans != null) {
        for (int i = 0; i < dependingBeans.length; i++) {
            destroySingleton(dependingBeans[i]);
        }
    }

    if (bean instanceof DisposableBean) {
        // 如果 bean 實(shí)現(xiàn)了 DisposableBean 接口,將會(huì)執(zhí)行 destroy 方法
        logger.debug("Calling destroy() on bean with name "" + beanName + """);
        try {
            ((DisposableBean) bean).destroy();
        }
        catch (Exception ex) {
            logger.error("destroy() on bean with name "" + beanName + "" threw an exception", ex);
        }
    }

    try {
        RootBeanDefinition bd = getMergedBeanDefinition(beanName, false);
        if (bd.getDestroyMethodName() != null) {
            // 如果 bean 定義了 destroy-method 屬性,將會(huì)調(diào)用自定義的銷毀方法
            logger.debug("Calling custom destroy method "" + bd.getDestroyMethodName() +
                                     "" on bean with name "" + beanName + """);
            invokeCustomDestroyMethod(beanName, bean, bd.getDestroyMethodName());
        }
    }
    catch (NoSuchBeanDefinitionException ex) {
        // ignore, from manually registered singleton
    }
}
下面將針對(duì) Spring Bean 在容器啟動(dòng)過程中的各個(gè)環(huán)節(jié)的實(shí)現(xiàn)進(jìn)行詳細(xì)說明
Spring Bean 定義解析

通過對(duì) refreshBeanFactory 方法的調(diào)用鏈追蹤,可以看到在 DefaultXmlBeanDefinitonParser 類的 registerBeanDefinitions 方法中實(shí)現(xiàn)對(duì) Spring Bean 定義的解析及注冊(cè)。

public void registerBeanDefinitions(BeanDefinitionRegistry beanFactory, ClassLoader beanClassLoader,
                                                                            Document doc, Resource resource) {
    this.beanFactory = beanFactory;
    this.beanClassLoader = beanClassLoader;
    this.resource = resource;

    logger.debug("Loading bean definitions");
    Element root = doc.getDocumentElement();

    this.defaultLazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
    logger.debug("Default lazy init "" + this.defaultLazyInit + """);
    this.defaultDependencyCheck = root.getAttribute(DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE);
    logger.debug("Default dependency check "" + this.defaultDependencyCheck + """);
    this.defaultAutowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
    logger.debug("Default autowire "" + this.defaultAutowire + """);

    NodeList nl = root.getChildNodes();
    int beanDefinitionCounter = 0;
    for (int i = 0; i < nl.getLength(); i++) {
        Node node = nl.item(i);
        if (node instanceof Element && BEAN_ELEMENT.equals(node.getNodeName())) {
            beanDefinitionCounter++;
            loadBeanDefinition((Element) node);
        }
    }
    logger.debug("Found " + beanDefinitionCounter + " <" + BEAN_ELEMENT + "> elements defining beans");
}
protected void loadBeanDefinition(Element ele) {
    // 獲取 bean 的 id, name 屬性
    String id = ele.getAttribute(ID_ATTRIBUTE);
    String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
    List aliases = new ArrayList();
    if (nameAttr != null && !"".equals(nameAttr)) {
        String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, BEAN_NAME_DELIMITERS, true, true);
        aliases.addAll(Arrays.asList(nameArr));
    }

    if (id == null || "".equals(id) && !aliases.isEmpty()) {
        id = (String) aliases.remove(0);
        logger.debug("No XML "id" specified - using "" + id + "" as ID and " + aliases + " as aliases");
    }

    // 解析 bean 標(biāo)簽, 獲取 bean 配置的屬性,構(gòu)造,是否懶加載 作用域
    AbstractBeanDefinition beanDefinition = parseBeanDefinition(ele, id);

    if (id == null || "".equals(id)) {
        if (beanDefinition instanceof RootBeanDefinition) {
            id = ((RootBeanDefinition) beanDefinition).getBeanClassName();
            logger.debug("Neither XML "id" nor "name" specified - using bean class name [" + id + "] as ID");
        }
        else {
            throw new BeanDefinitionStoreException(this.resource, "","Child bean definition has neither "id" nor "name"");
        }
    }

    logger.debug("Registering bean definition with id "" + id + """);
    // 將 bean definiton 注冊(cè)到 beanFactory
    this.beanFactory.registerBeanDefinition(id, beanDefinition);
    for (Iterator it = aliases.iterator(); it.hasNext();) {
        this.beanFactory.registerAlias(id, (String) it.next());
    }
}
protected AbstractBeanDefinition parseBeanDefinition(Element ele, String beanName) {
    String className = null;
    try {
        // 獲取 class 屬性
        if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
            className = ele.getAttribute(CLASS_ATTRIBUTE);
        }
        String parent = null;
        if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
            parent = ele.getAttribute(PARENT_ATTRIBUTE);
        }
        if (className == null && parent == null) {
            throw new BeanDefinitionStoreException(this.resource, beanName, "Either "class" or "parent" is required");
        }

        AbstractBeanDefinition bd = null;
        // 獲取屬性
        MutablePropertyValues pvs = getPropertyValueSubElements(beanName, ele);

        if (className != null) {
            // 獲取構(gòu)造
            ConstructorArgumentValues cargs = getConstructorArgSubElements(beanName, ele);
            RootBeanDefinition rbd = null;

            if (this.beanClassLoader != null) {
                Class clazz = Class.forName(className, true, this.beanClassLoader);
                rbd = new RootBeanDefinition(clazz, cargs, pvs);
            }
            else {
                rbd = new RootBeanDefinition(className, cargs, pvs);
            }
            // 設(shè)置 bean dependOn
            if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
                String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
                rbd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, BEAN_NAME_DELIMITERS, true, true));
            }

            String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
            if (DEFAULT_VALUE.equals(dependencyCheck)) {
                dependencyCheck = this.defaultDependencyCheck;
            }
            rbd.setDependencyCheck(getDependencyCheck(dependencyCheck));

            // 設(shè)置 bean 自動(dòng)注冊(cè)的方式 byType, byName or none
            String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
            if (DEFAULT_VALUE.equals(autowire)) {
                autowire = this.defaultAutowire;
            }
            rbd.setAutowireMode(getAutowireMode(autowire));

            // 設(shè)置 bean 的 init-method
            String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
            if (!initMethodName.equals("")) {
                rbd.setInitMethodName(initMethodName);
            }

            // 設(shè)置 bean 的 destroy-method
            String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
            if (!destroyMethodName.equals("")) {
                rbd.setDestroyMethodName(destroyMethodName);
            }

            bd = rbd;
        }
        else {
            bd = new ChildBeanDefinition(parent, pvs);
        }

        // 設(shè)置 bean 是否為單例
        if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
            bd.setSingleton(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)));
        }

        // 是否懶加載
        String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
        if (DEFAULT_VALUE.equals(lazyInit) && bd.isSingleton()) {
            // just apply default to singletons, as lazy-init has no meaning for prototypes
            lazyInit = this.defaultLazyInit;
        }
        bd.setLazyInit(TRUE_VALUE.equals(lazyInit));

        bd.setResourceDescription(this.resource.getDescription());

        return bd;
    }
    catch (ClassNotFoundException ex) {
    }
    catch (NoClassDefFoundError err) {}
}
Spring 容器在將配置文件加載后,會(huì)解析 bean 標(biāo)簽并通過其相應(yīng)的屬性配置構(gòu)造 BeanDefinition 對(duì)象,然后將 BeanDefinition 對(duì)象注冊(cè)添加到 BeanFactory 中。
Spring Bean 實(shí)例化
public void preInstantiateSingletons() {
    if (logger.isInfoEnabled()) {
        logger.info("Pre-instantiating singletons in factory [" + this + "]");
    }
    // 遍歷注冊(cè)的 bean definition
    for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();) {
        String beanName = (String) it.next();
        if (containsBeanDefinition(beanName)) {
            RootBeanDefinition bd = getMergedBeanDefinition(beanName, false);
            // 如果 bean 定義為單例且非延遲加載的
            if (bd.isSingleton() && !bd.isLazyInit()) {
                // 判斷 bean 是否為 FactoryBean
                if (FactoryBean.class.isAssignableFrom(bd.getBeanClass())) {
                    FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (factory.isSingleton()) {
                        getBean(beanName);
                    }
                }
                else {
                    // 若是普通 bean 則調(diào)用 getBean
                    getBean(beanName);
                }
            }
        }
    }
}
public Object getBean(String name) throws BeansException {
    String beanName = transformedBeanName(name);
    // eagerly check singleton cache for manually registered singletons
    // 檢查單例緩存池中 是否存在 bean 實(shí)例,如果有從緩存中獲取 bean 實(shí)例
    Object sharedInstance = this.singletonCache.get(beanName);
    if (sharedInstance != null) {
        if (logger.isDebugEnabled()) {
            logger.debug("Returning cached instance of singleton bean "" + beanName + """);
        }
        return getObjectForSharedInstance(name, sharedInstance);
    }
    else {
        // check if bean definition exists
        RootBeanDefinition mergedBeanDefinition = null;
        try {
            mergedBeanDefinition = getMergedBeanDefinition(beanName, false);
        }
        catch (NoSuchBeanDefinitionException ex) {
            // not found -> check parent
            if (this.parentBeanFactory != null) {
                return this.parentBeanFactory.getBean(name);
            }
            throw ex;
        }
        // create bean instance
        if (mergedBeanDefinition.isSingleton()) {
            synchronized (this.singletonCache) {
                // re-check singleton cache within synchronized block
                sharedInstance = this.singletonCache.get(beanName);
                if (sharedInstance == null) {
                    logger.info("Creating shared instance of singleton bean "" + beanName + """);
                    sharedInstance = createBean(beanName, mergedBeanDefinition);
                    addSingleton(beanName, sharedInstance);
                }
            }
            return getObjectForSharedInstance(name, sharedInstance);
        }
        else {
            return createBean(name, mergedBeanDefinition);
        }
    }
}
protected Object createBean(String beanName, RootBeanDefinition mergedBeanDefinition) throws BeansException {
    if (mergedBeanDefinition.getDependsOn() != null) {
        for (int i = 0; i < mergedBeanDefinition.getDependsOn().length; i++) {
            // guarantee initialization of beans that the current one depends on
            getBean(mergedBeanDefinition.getDependsOn()[i]);
        }
    }

    // bean 初始化并包裝,也就是 new
    BeanWrapper instanceWrapper = null;
    if (mergedBeanDefinition.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
            mergedBeanDefinition.hasConstructorArgumentValues()) {
        instanceWrapper = autowireConstructor(beanName, mergedBeanDefinition);
    }
    else {
        instanceWrapper = new BeanWrapperImpl(mergedBeanDefinition.getBeanClass());
        initBeanWrapper(instanceWrapper);
    }
    Object bean = instanceWrapper.getWrappedInstance();

    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    if (mergedBeanDefinition.isSingleton()) {
        // 單例的bean 則添加到緩存中
        addSingleton(beanName, bean);
    }
    // bean 屬性注入
    populateBean(beanName, mergedBeanDefinition, instanceWrapper);

    try {
        if (bean instanceof BeanNameAware) {
            // bean 若實(shí)現(xiàn)接口 BeanNameAware 則調(diào)用 setBeanName 方法
            ((BeanNameAware) bean).setBeanName(beanName);
        }

        if (bean instanceof BeanFactoryAware) {
            // bean 若實(shí)現(xiàn)接口 BeanFactoryAware 則調(diào)用 setBeanFactory 方法
            ((BeanFactoryAware) bean).setBeanFactory(this);
        }

        // 調(diào)用 BeanPostProcessor 執(zhí)行 postProcessBeforeInitialization 方法
        bean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        // 若 bean 實(shí)現(xiàn) InitializingBean 接口則執(zhí)行 afterPropertiesSet 方法
        // 若 bean 定義中定義了 init-method 屬性則執(zhí)行對(duì)應(yīng)的init 方法
        invokeInitMethods(bean, beanName, mergedBeanDefinition);
        // 調(diào)用 BeanPostProcessor 執(zhí)行 postProcessAfterInitialization 方法
        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    }
    catch (InvocationTargetException ex) {
        throw new BeanCreationException(mergedBeanDefinition.getResourceDescription(), beanName,
                                                                        "Initialization of bean failed", ex.getTargetException());
    }
    catch (Exception ex) {
        throw new BeanCreationException(mergedBeanDefinition.getResourceDescription(), beanName,
                                                                        "Initialization of bean failed", ex);
    }
    return bean;
}
從 bean 的實(shí)例化過程中,Spring 容器在啟動(dòng)時(shí)只針對(duì)單例且非延遲加載的 bean 進(jìn)行初始化;其他的 bean 只有在顯示調(diào)用 getBean() 方法時(shí)才去實(shí)例化;下面將會(huì)對(duì)實(shí)例化過程中的詳細(xì)過程進(jìn)行說明。
Spring Bean 作用域
singleton 單例模式
Spring IoC 容器中只會(huì)存在一個(gè)共享的Bean實(shí)例,無論有多少個(gè)Bean引用它,始終指向同一對(duì)象。
    

    

Spring 1.0 中通過 bean 定義屬性 singleton="true" 表示單例; 在 Spring 2.x 之后版本改為定義屬性 scope="singleton", 同時(shí)兼容 1.0 的配置

prototype 原型模式
每次通過Spring容器獲取prototype定義的bean時(shí),容器都將創(chuàng)建一個(gè)新的Bean實(shí)例,每個(gè)Bean實(shí)例都有自己的屬性和狀態(tài)
    

    

Spring 1.0 中通過 bean 定義屬性 singleton="false" 表示原型模式; 在 Spring 2.x 之后版本改為定義屬性 scope="prototype", 同時(shí)兼容 1.0 的配置

Spring Bean 生命周期

示例
public class LifecycleBean implements BeanNameAware, InitializingBean, BeanFactoryAware, ResourceLoaderAware, ApplicationContextAware, DisposableBean {

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("set bean factory");
    }

    public void setBeanName(String name) {
        System.out.println("set bean name");
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("Initializing Bean afterPropertiesSet");
    }

    public void setApplicationContext(ApplicationContext context) throws BeansException {
        System.out.println("set application context");
    }

    public void setResourceLoader(ResourceLoader resourceLoader) {
        System.out.println("set resource loader");
    }

    public void init () {
        System.out.println("do init method");
    }

    public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
        System.out.println("post Process Before Initialization");
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
        System.out.println("post Process After Initialization");
        return bean;
    }

    public void destroy() throws Exception {
        System.out.println("do destroy ");
    }

    public void destroyMethod() throws Exception {
        System.out.println("do destroy method");
    }
}
public class PostProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
        if (bean instanceof LifecycleBean) {
            ((LifecycleBean) bean).postProcessBeforeInitialization(bean, name);
        }
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
        if (bean instanceof LifecycleBean) {
            ((LifecycleBean) bean).postProcessAfterInitialization(bean, name);
        }
        return bean;
    }
}

spring 配置文件如下


    

    

運(yùn)行結(jié)果如下:

set bean name
set bean factory
set resource loader
set application context
post Process Before Initialization
Initializing Bean afterPropertiesSet
do init method
post Process After Initialization
do destroy 
do destroy method
Spring Bean 注入方式
構(gòu)造注入

    
        
    


當(dāng) bean 定義配置如以上方式的時(shí)候,會(huì)觸發(fā) autowireConstructor (詳細(xì)實(shí)現(xiàn)參考源碼吧)

BeanWrapper instanceWrapper = null;
if (mergedBeanDefinition.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
        mergedBeanDefinition.hasConstructorArgumentValues()) {

    instanceWrapper = autowireConstructor(beanName, mergedBeanDefinition);
}
byType 注入

當(dāng) bean 定義配置如以上方式的時(shí)候,會(huì)觸發(fā) autowireByType 如下:

protected void autowireByType(String beanName, RootBeanDefinition mergedBeanDefinition,
                                                                BeanWrapper bw, MutablePropertyValues pvs) {
    // 查找 bean 存在可寫方法的非基本數(shù)據(jù)類型的成員變量
    String[] propertyNames = unsatisfiedObjectProperties(mergedBeanDefinition, bw);
    for (int i = 0; i < propertyNames.length; i++) {
        String propertyName = propertyNames[i];
        // look for a matching type
        // 獲取成員變量的類型
        Class requiredType = bw.getPropertyDescriptor(propertyName).getPropertyType();
        // 查找成員變量對(duì)應(yīng)的 bean 實(shí)例
        Map matchingBeans = findMatchingBeans(requiredType);
        if (matchingBeans != null && matchingBeans.size() == 1) {
            // 成員變量查找到匹配的bean實(shí)例,有且只有一個(gè)的時(shí)候
            // 將屬性名和屬性值 添加到 PropertyValues 中
            pvs.addPropertyValue(propertyName, matchingBeans.values().iterator().next());
            if (logger.isDebugEnabled()) {
                logger.debug("Autowiring by type from bean name "" + beanName +
                                        "" via property "" + propertyName + "" to bean named "" +
                                        matchingBeans.keySet().iterator().next() + """);
            }
        }
        else if (matchingBeans != null && matchingBeans.size() > 1) {
            // 當(dāng)存在多個(gè)同類型的實(shí)例時(shí) 拋出異常
            throw new UnsatisfiedDependencyException(beanName, propertyName,
                    "There are " + matchingBeans.size() + " beans of type [" + requiredType + "] for autowire by type. " +
                    "There should have been 1 to be able to autowire property "" + propertyName + "" of bean "" + beanName + "".");
        }
        else {
            if (logger.isDebugEnabled()) {
                logger.debug("Not autowiring property "" + propertyName + "" of bean "" + beanName +
                                        "" by type: no matching bean found");
            }
        }
    }
}
byName 注入

當(dāng) bean 定義配置如以上方式的時(shí)候,會(huì)觸發(fā) autowireByName 如下:

protected void autowireByName(String beanName, RootBeanDefinition mergedBeanDefinition,
                                                                BeanWrapper bw, MutablePropertyValues pvs) {
    // 查找 bean 存在可寫方法的非基本數(shù)據(jù)類型的成員變量
    String[] propertyNames = unsatisfiedObjectProperties(mergedBeanDefinition, bw);
    for (int i = 0; i < propertyNames.length; i++) {
        String propertyName = propertyNames[i];
        // 在 Spring 容器中查找是否存在以 propertyName 命名的 bean definition
        if (containsBean(propertyName)) {
            // 實(shí)例化依賴的 bean, 并添加到 MutablePropertyValues 中
            Object bean = getBean(propertyName);
            pvs.addPropertyValue(propertyName, bean);
            if (logger.isDebugEnabled()) {
                logger.debug("Added autowiring by name from bean name "" + beanName +
                    "" via property "" + propertyName + "" to bean named "" + propertyName + """);
            }
        }
        else {
            if (logger.isDebugEnabled()) {
                logger.debug("Not autowiring property "" + propertyName + "" of bean "" + beanName +
                                        "" by name: no matching bean found");
            }
        }
    }
}
set 注入

    
        11
    

當(dāng) bean 定義配置如上,或者采用 byName, byType 的注入方式時(shí),都會(huì)調(diào)用 applyPropertyValues 方法完成屬性的注入。(詳細(xì)實(shí)現(xiàn)參考源碼吧)

Spring Bean 注解式注入
自 Spring 2.5 版本之后,支持通過注解方式實(shí)現(xiàn) Bean 的自動(dòng)注入,譬如 @Autowired, @Resource 等注解

為了引入注解式自動(dòng)注入, Spring 在 2.x 版本中新增了 InstantiationAwareBeanPostProcessor 接口,該接口繼承 BeanPostProcessor 并新增了方法 postProcessPropertyValues ; 該方法主要實(shí)現(xiàn)

Post-process the given property values before the factory applies them to the given bean
Autowired 注解
采用 Autowired 注解實(shí)現(xiàn)自動(dòng)注入,需在配置文件中配置 AutowiredAnnotationBeanPostProcessor Bean
public AutowiredAnnotationBeanPostProcessor() {
    this.autowiredAnnotationTypes.add(Autowired.class);
    this.autowiredAnnotationTypes.add(Value.class);
    ClassLoader cl = AutowiredAnnotationBeanPostProcessor.class.getClassLoader();
    try {
        this.autowiredAnnotationTypes.add((Class) cl.loadClass("javax.inject.Inject"));
        logger.info("JSR-330 "javax.inject.Inject" annotation found and supported for autowiring");
    }
    catch (ClassNotFoundException ex) {
        // JSR-330 API not available - simply skip.
    }
}

AutowiredAnnotationBeanPostProcessor 構(gòu)造可以看出其支持 @Autowired,@Value,@Inject 注解的自動(dòng)注入。 下面大概看下其如何實(shí)現(xiàn)自動(dòng)注入

public PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
    // 查找 bean 中需要自動(dòng)注入的元數(shù)據(jù),包括 field, method
    InjectionMetadata metadata = findAutowiringMetadata(bean.getClass());
    try {
        // 實(shí)現(xiàn)注入
        metadata.inject(bean, beanName, pvs);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
    }
    return pvs;
}
Resource 注解
采用 Resource 注解實(shí)現(xiàn)自動(dòng)注入,需在配置文件中配置 CommonAnnotationBeanPostProcessor Bean
public CommonAnnotationBeanPostProcessor() {
    setOrder(Ordered.LOWEST_PRECEDENCE - 3);
    setInitAnnotationType(PostConstruct.class);
    setDestroyAnnotationType(PreDestroy.class);
    ignoreResourceType("javax.xml.ws.WebServiceContext");
}

CommonAnnotationBeanPostProcessor 構(gòu)造可以看出,該類同時(shí)支持對(duì)注解 @PostConstruct, @PreDestroy 生效。

public PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
    // 查找 bean 中標(biāo)注有 @Resource 注解的 Field, method
    InjectionMetadata metadata = findResourceMetadata(bean.getClass());
    try {
        // 實(shí)現(xiàn)注入
        metadata.inject(bean, beanName, pvs);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
    }
    return pvs;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    // 查找 bean 定義中標(biāo)注了 PostConstruct 注解的方法
    LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    try {
        // 調(diào)用指定 post construct method
        metadata.invokeInitMethods(bean, beanName);
    }
    catch (InvocationTargetException ex) {
        throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Couldn"t invoke init method", ex);
    }
    return bean;
}

public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
    // 查找 bean 定義中標(biāo)注了 PreDestroy 注解的方法
    LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    try {
        // 調(diào)用指定 destroy method
        metadata.invokeDestroyMethods(bean, beanName);
    }
    catch (InvocationTargetException ex) {
        String msg = "Invocation of destroy method failed on bean with name "" + beanName + """;
        if (logger.isDebugEnabled()) {
            logger.warn(msg, ex.getTargetException());
        }
        else {
            logger.warn(msg + ": " + ex.getTargetException());
        }
    }
    catch (Throwable ex) {
        logger.error("Couldn"t invoke destroy method on bean with name "" + beanName + """, ex);
    }
}
private LifecycleMetadata buildLifecycleMetadata(Class clazz) {
    final boolean debug = logger.isDebugEnabled();
    LinkedList initMethods = new LinkedList();
    LinkedList destroyMethods = new LinkedList();
    Class targetClass = clazz;

    do {
        LinkedList currInitMethods = new LinkedList();
        LinkedList currDestroyMethods = new LinkedList();
        // 遍歷 bean 的所有方法
        for (Method method : targetClass.getDeclaredMethods()) {
            if (this.initAnnotationType != null) {
                // 判斷 method 是否標(biāo)注了 @PostConstruct 注解
                if (method.getAnnotation(this.initAnnotationType) != null) {
                    LifecycleElement element = new LifecycleElement(method);
                    currInitMethods.add(element);
                    if (debug) {
                        logger.debug("Found init method on class [" + clazz.getName() + "]: " + method);
                    }
                }
            }
            if (this.destroyAnnotationType != null) {
                // 判斷 method 是否標(biāo)注了 @PreDestroy 注解
                if (method.getAnnotation(this.destroyAnnotationType) != null) {
                    currDestroyMethods.add(new LifecycleElement(method));
                    if (debug) {
                        logger.debug("Found destroy method on class [" + clazz.getName() + "]: " + method);
                    }
                }
            }
        }
        initMethods.addAll(0, currInitMethods);
        destroyMethods.addAll(currDestroyMethods);
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    return new LifecycleMetadata(clazz, initMethods, destroyMethods);
}
為了簡(jiǎn)化 Spring 配置文件中的 bean 配置,Spring 提供了  標(biāo)簽自動(dòng)加載 AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor 等 bean。

在 spring-context 包 resources/META-INF 下的 spring.handlers 文件中配置如下:

http://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
public class ContextNamespaceHandler extends NamespaceHandlerSupport {

    public void init() {
        registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
        registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
        registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
        registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
        registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
        registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
        registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
        registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
    }

}
public static Set registerAnnotationConfigProcessors(
            BeanDefinitionRegistry registry, Object source) {

    Set beanDefs = new LinkedHashSet(4);

    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        // 加載注冊(cè) AutowiredAnnotationBeanPostProcessor
        RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        // 加載注冊(cè) RequiredAnnotationBeanPostProcessor
        RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
    if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        // 加載注冊(cè) CommonAnnotationBeanPostProcessor
        RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
    if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition();
        try {
            ClassLoader cl = AnnotationConfigUtils.class.getClassLoader();
            def.setBeanClass(cl.loadClass(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME));
        }
        catch (ClassNotFoundException ex) {
            throw new IllegalStateException(
                    "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
        }
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    return beanDefs;
}

可以看出在 Spring 啟動(dòng)時(shí),通過解析 標(biāo)簽,完成對(duì) CommonAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor 的加載注冊(cè),進(jìn)而實(shí)現(xiàn)通過注解方式的自動(dòng)注入。

小結(jié) BeanFactory & ApplicationContext

BeanFactoryPostProcessor & BeanPostProcessor

BeanFactoryPostProcessorApplicationContext 在 BeanFactory 完成創(chuàng)建后對(duì)其進(jìn)行后置處理的接口

BeanPostProcessorBeanFactory 在 Bean 完成實(shí)例化對(duì)其進(jìn)行的后置處理接口

BeanFactory & FactoryBean

BeanFactory 是 Spring 框架底層的核心接口,其提供了創(chuàng)建 bean,獲取 bean 等核心功能。

FactoryBean 是生產(chǎn) bean 的一個(gè)模式,也就是以工廠模式的方式生產(chǎn) bean。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/73511.html

相關(guān)文章

  • 重拾css(1)——寫在前邊的話

    摘要:本系列文章重拾主要參考王福朋知多少,結(jié)合自己的理解和學(xué)習(xí)需要,修改或添加了一些內(nèi)容,難免有失偏頗,僅供自我學(xué)習(xí)參考之用。 工作中或多或少的寫一些css,但總感覺掌握的不夠扎實(shí),時(shí)而需要查閱一下知識(shí)點(diǎn)。我想,一方面跟缺少科班出身式的系統(tǒng)學(xué)習(xí)有關(guān),另一方面也苦于一直未尋覓到一套合我胃口教程。直到我讀到了王福朋css知多少系列文章,使我有了重新系統(tǒng)學(xué)習(xí)css的想法。 本系列文章(重拾css)...

    li21 評(píng)論0 收藏0
  • CSS魔法堂:重拾Border之——更廣闊的遐想

    摘要:也就是說我們操作的幾何公式中的未知變量,而具體的畫圖操作則由渲染引擎處理,而不是我們苦苦哀求設(shè)計(jì)師幫忙。 前言 ?當(dāng)CSS3推出border-radius屬性時(shí)我們是那么欣喜若狂啊,一想到終于不用再添加額外元素來模擬圓角了,但發(fā)現(xiàn)border-radius還分水平半徑和垂直半徑,然后又發(fā)現(xiàn)border-top-left/right-radius的水平半徑之和大于元素寬度時(shí),實(shí)際值會(huì)按比...

    lily_wang 評(píng)論0 收藏0
  • CSS魔法堂:重拾Border之——解構(gòu)Border

    摘要:本系列將稍微深入探討一下那個(gè)貌似沒什么好玩的魔法堂重拾之解構(gòu)魔法堂重拾之圖片作邊框魔法堂重拾之不僅僅是圓角魔法堂重拾之更廣闊的遐想解構(gòu)說起我們自然會(huì)想起,而由條緊緊包裹著的邊組成,所以的最小操作單元是。 前言 ?當(dāng)CSS3推出border-radius屬性時(shí)我們是那么欣喜若狂啊,一想到終于不用再添加額外元素來模擬圓角了,但發(fā)現(xiàn)border-radius還分水平半徑和垂直半徑,然后又發(fā)現(xiàn)...

    lingdududu 評(píng)論0 收藏0
  • spring-ioc流程源碼解析

    摘要:中的流程中的方法是啟動(dòng)加載整個(gè)容器的關(guān)鍵方法。此函數(shù)第一步將流轉(zhuǎn)換成的,接下來就是解析,轉(zhuǎn)換成的然后注冊(cè)到中的一個(gè)中去?,F(xiàn)在馬上就要開始解析了,真正的解析就在方法,是指,標(biāo)簽就是此下的,所以會(huì)走。至此,的流程就走完了。 Spring中ioc的流程 AbstractApplicationContext 中的refresh()方法是啟動(dòng)加載整個(gè)容器的關(guān)鍵方法。 在refresh()方法中...

    zorpan 評(píng)論0 收藏0
  • 架構(gòu)~微服務(wù)

    摘要:接下來繼續(xù)介紹三種架構(gòu)模式,分別是查詢分離模式微服務(wù)模式多級(jí)緩存模式。分布式應(yīng)用程序可以基于實(shí)現(xiàn)諸如數(shù)據(jù)發(fā)布訂閱負(fù)載均衡命名服務(wù)分布式協(xié)調(diào)通知集群管理選舉分布式鎖和分布式隊(duì)列等功能。 SpringCloud 分布式配置 SpringCloud 分布式配置 史上最簡(jiǎn)單的 SpringCloud 教程 | 第九篇: 服務(wù)鏈路追蹤 (Spring Cloud Sleuth) 史上最簡(jiǎn)單的 S...

    xinhaip 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<