關於如何動態手動注入Spring容器中bean對象(代碼實現)


一、需求產生原因:

通過修改Spring容器中對象中某個屬性,該對象被spring其他服務調用,可以動態實現調用方實現不同的業務邏輯。

 

二、涉及spring相關對象:

  1. DefaultListableBeanFactory:IOC容器始祖

默認實現了ListableBeanFactory和BeanDefinitionRegistry接口,基於bean definition對象,是一個成熟的bean factroy。

最典型的應用是:在訪問bean前,先注冊所有的definition(可能從bean definition配置文件中)。使用預先建立的bean定義元數據對象,從本地的bean definition表中查詢bean definition因而將不會花費太多成本。

DefaultListableBeanFactory既可以作為一個單獨的beanFactory,也可以作為自定義beanFactory的父類。

      

 

 

三、關於其部分內部方法:

1.getBean():獲取容器中對象

public Object getBean(String name) throws BeansException {
        return this.doGetBean(name, (Class)null, (Object[])null, false);
    }

    public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
        return this.doGetBean(name, requiredType, (Object[])null, false);
    }

    public Object getBean(String name, Object... args) throws BeansException {
        return this.doGetBean(name, (Class)null, args, false);
    }

    public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args) throws BeansException {
        return this.doGetBean(name, requiredType, args, false);
    }

 

 

 

2. removeBeanDereference():刪除bean對象定義

public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
        Assert.hasText(beanName, "'beanName' must not be empty");
        BeanDefinition bd = (BeanDefinition)this.beanDefinitionMap.remove(beanName);
        if (bd == null) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("No bean named '" + beanName + "' found in " + this);
            }

            throw new NoSuchBeanDefinitionException(beanName);
        } else {
            if (this.hasBeanCreationStarted()) {
                synchronized(this.beanDefinitionMap) {
                    List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames);
                    updatedDefinitions.remove(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                }
            } else {
                this.beanDefinitionNames.remove(beanName);
            }

            this.frozenBeanDefinitionNames = null;
            this.resetBeanDefinition(beanName);
        }
    }

 

 

 

3.registerBeanDefinition():重新注冊bean定義

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");
        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {
                ((AbstractBeanDefinition)beanDefinition).validate();
            } catch (BeanDefinitionValidationException var9) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9);
            }
        }

        BeanDefinition oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
        if (oldBeanDefinition != null) {
            if (!this.isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound.");
            }

            if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                }
            } else if (!beanDefinition.equals(oldBeanDefinition)) {
                if (this.logger.isInfoEnabled()) {
                    this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                }
            } else if (this.logger.isDebugEnabled()) {
                this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
            }

            this.beanDefinitionMap.put(beanName, beanDefinition);
        } else {
            if (this.hasBeanCreationStarted()) {
                synchronized(this.beanDefinitionMap) {
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    updatedDefinitions.add(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                    if (this.manualSingletonNames.contains(beanName)) {
                        Set<String> updatedSingletons = new LinkedHashSet(this.manualSingletonNames);
                        updatedSingletons.remove(beanName);
                        this.manualSingletonNames = updatedSingletons;
                    }
                }
            } else {
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                this.manualSingletonNames.remove(beanName);
            }

            this.frozenBeanDefinitionNames = null;
        }

        if (oldBeanDefinition != null || this.containsSingleton(beanName)) {
            this.resetBeanDefinition(beanName);
        }

    }

                    

 

四、主要實現方法

方法解讀

  1. 先判斷容器中是否包含該對象
  2. 包含則刪除該對象
  3. 生成Bean定義生成器(BeanDefinitionBuilder),此處會默認調用該對象的無參構造方法,用於注入該實例。
  4. 通過生成器生成BeadDefinition;
  5. 然后設定部分BeadDefinition部分屬性參數,其他默認
  6. 通過方法重寫初始化注入該對象
  7. 工具方法
 /**
     * 動態注入對象
     * @param beanName bean對象名稱
     * @param beanClass bean對象class類型
     */
    private void dynamicInjectionObj(String beanName, Class<?> beanClass) {
        boolean containsBean = defaultListableBeanFactory.containsBean(beanName);
        if (containsBean) {
            defaultListableBeanFactory.removeBeanDefinition(beanName);
        }

        //默認使用對象的無參構造方法:此對象已經重寫無參構造(此處會重新實例化一個新對象)
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(beanClass);
        //構造注入對象參數
        AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
        beanDefinition.setAutowireMode(2);
        beanDefinition.setPrimary(true);
        beanDefinition.setSynthetic(true);
//        beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        beanDefinition.setScope("singleton");
        beanDefinition.setRole(0);

        defaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinition);

    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM