Spring基礎(chǔ)知識二

一、依賴注入

Spring 從核心而言,是一個DI 容器,其設計哲學是提供一種無侵入式的高擴展性框架。即無需代碼中涉及Spring專有類,即可將其納入Spring容器進行管理。作為對比,EJB則是一種高度侵入性的框架規(guī)范,它制定了眾多的接口和編碼規(guī)范,要求實現(xiàn)者必須遵從。侵入性的后果就是,一旦系統(tǒng)基于侵入性框架設計開發(fā),那么之后任何脫離這個框架的企圖都將付出極大的代價。為了避免這種情況,實現(xiàn)無侵入性的目標。Spring 大量引入了Java 的Reflection機制,通過動態(tài)調(diào)用的方式避免硬編碼方式的約束,并在此基礎(chǔ)上建立了其核心組件BeanFactory,以此作為其依賴注入機制的實現(xiàn)基礎(chǔ)。org.springframework.beans包中包括了這些核心組件的實現(xiàn)類,核心中的核心為BeanWrapper和BeanFactory類。這兩個類從技術(shù)角度而言并不復雜,但對于Spring 框架而言,卻是關(guān)鍵所在。

1、Spring兩種屬性注入的方式:

1.set方式注入

<bean id="user" class="com.spring.demo1.User" scope="singleton">
   <!-- 注入屬性值 name的屬性值就是類里面定義的屬性名稱 value設置具值-->
   <property name="bookname" value="程序設計"></property>
 </bean>

2.有參構(gòu)造注入

<bean id="user1" class="com.boss.domain.User1">
    <constructor-arg name="username" value="李四" />
</bean>

2、手寫依賴注入(Set方式注入底層原理)

要想實現(xiàn)依賴注入,首先我們需要在BeanDefinition中定義屬性的鍵值對:
實際BeanDefinition中存放對象屬性的是BeanDefinition的propertyValues屬性,它是一個列表,存放的是包含有對象屬性信息的對象:PropertyValue

    //存放屬性鍵值對
    private Map<String, String> propertyMap = new HashMap<>(16);

在BeanFactory中返回實例化對象前,給對象賦值。實現(xiàn)setvalue方法:

private void setValue(Object instance, Class beanField, Map<String, String> propertyMap) throws Exception {
        //獲取所有的方法
        Method[] methods = beanField.getDeclaredMethods();
        //對properMap進行解析,獲取鍵值對,也就是需要注入的屬性和屬性值
        Set<String> propertySet = propertyMap.keySet();
        Iterator<String> propertyIterator = propertySet.iterator();
        while (propertyIterator.hasNext()){
            String propertyKey = propertyIterator.next();
            String propertyValue = propertyMap.get(propertyKey);
            //獲取的屬性
            Field field = beanField.getDeclaredField(propertyKey);
            //屬性對應的set方法
            String methodName = "set" + field.getName();
            //對方法進行過濾
            for (int i = 0; i < methods.length; i ++){
                Method method = methods[i];
                if (methodName.equalsIgnoreCase(method.getName())){
                    //判斷set方法的類型 也就是屬性的類型
                    Class fieldType = field.getType();
                    if (fieldType == String.class){
                        method.invoke(instance, propertyValue);
                    } else if (fieldType == Integer.class){
                        method.invoke(instance, Integer.valueOf(propertyValue));
                        //這里只對List類型做判斷
                    } else if (fieldType == List.class){
                        List<String> tmpList = new ArrayList<>(16);
                        String[] itemArray = propertyValue.split(",");
                        for (int j = 0; j < itemArray.length; j ++){
                            tmpList.add(itemArray[i]);
                        }
                    }else {
                        throw new RuntimeException("暫不該支持屬性類型注入");
                    }
                }
            }
        }
    }

實現(xiàn)邏輯不難,就是一層一層解析,基本步驟可以看注解。測試類:TestMain

 @Test
    public void testPropertyMap() throws Exception {
        //注冊bean
        BeanDefined beanObj = new BeanDefined();
        beanObj.setBeanId("user");
        beanObj.setClassPath("com.lks.bean.User");

        //設置propertyMap 類似Spring中依賴注入屬性值
        Map<String, String> propertyMap = beanObj.getPropertyMap();
        propertyMap.put("name", "蕭峰");
        propertyMap.put("age", "31");
        propertyMap.put("sex", "男");

        List<BeanDefined> beanDefineds = new ArrayList<>(16);
        beanDefineds.add(beanObj);

        //聲明BeanFactory,類似于Spring中的ApplicationContext
        BeanFactory factory = new BeanFactory(beanDefineds);

        //實際調(diào)用
        User user = (User) factory.getPropertyBean("user");
        System.out.println(user.toString());
    }

3、BeanDefinition擴展


BeanDefinitionBuilder已經(jīng)是最頂層應用,可以利用BeanDefinitionBuilder生成BeanDefinition:

BeanDefinition beanDefinition= BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();

BeanDefinition屬性內(nèi)容:


二、Bean的生命周期

https://www.cnblogs.com/liurg/p/7942374.html
屬性注入的形式:
基于XML
基于?

手寫依賴注入:
https://blog.csdn.net/lks1139230294/article/details/88201149

什么是IOC
https://www.cnblogs.com/XiOrang/p/9337991.html

依賴注入與自動裝配的關(guān)系
https://blog.csdn.net/qq_20367813/article/details/80940366

自動裝配的方式有哪些?
https://www.pianshen.com/article/294442824/

AOP實戰(zhàn)

抽象方法與多態(tài):

動態(tài)代理底層原理

Autowired的底層:getBean

動態(tài)代理底層邏輯

如何進行屬性填充:
http://www.itdecent.cn/p/20cf0116c5c0

Spring中屬性注入的幾種方式以及復雜屬性的注入詳解
spring依賴注入的實現(xiàn)原理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容