91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring注入模型怎么應用

發布時間:2023-04-27 17:38:19 來源:億速云 閱讀:128 作者:iii 欄目:開發技術

今天小編給大家分享一下Spring注入模型怎么應用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

    Spring注入bean的方式

    DI exists in two major variants: Constructor-based dependency injection and Setter-based dependency injection.

    從Spring的官網中可以得知,Spring注入bean的方式由兩種,一種是通過構造方法進行注入,另外一種是通過setter方法進行注入。
    但熟悉Spring開發的同學在實際的開發中經常使用的注入方式是通過@Autowired以及@Resource的方式來注入bean的。那么通過注解的方式注入是跟上面兩種注入方式是一樣的嗎?在研究這個問題之前,我們需要來了解Spring的注入模型。

    Spring的注入模型

    如果不深入到Spring的源碼,是很少有機會了解到Spring的注入模型(AutowireMode)。但是為了掃清我們學習Spring源碼的障礙,我們有必要了解下Spring的注入模型。
    Spring的注入模型有四種,分別是:

    • autowire_no(0):默認的注入模型,如果在beanA中注入beanB,如果沒有提供注解或者xml的注入方式,beanB是無法注入到beanA中的。

    • autowire_name(1):通過set方法注入,并且set的參數名必須和注入的bean名稱一樣,在xml中是通過byName

    • autowire_type(2):通過set方法注入,set的參數名可以隨意命名,但是類型必須和注入的bean的類型一樣,在xml中是通過byType的方式配置

    • autowire_constructor(3):通過構造器注入

    代碼示例

    多說無益,我們直接上代碼來加深對這一概念的了解。

    定義bean對象

    我們簡單定義兩個類,分別是Student和Address,并且將他們注入到Spring容器中。
    Student.java如下

    @Component
    @Slf4j
    public class Student {
    
        private Address address;
    
        public Student(){
            log.info("default constructor...");
        }
    
        public Student(Address address){
            log.info("constructor inject...{}", address);
            this.address = address;
        }
    
        public void setAddress(Address address){
            log.info("setter...{}", address);
            this.address = address;
        }
    
        public void showAddress(){
            this.address.info();
        }
    }

    Address.java如下

    @Component
    public class Address {
    
        public void info(){
            System.out.println("廣東省廣州市白云區");
        }
    }

    我們可以看到在Student中有一個屬性是Address,并且提供了默認的構造方法以及帶參數的構造方法,同時還有一個 set方法。

    定義配置類

    我們再定義一個config類,用來掃描這兩個類所在的包路徑,把這兩個類注入到Spring容器中。

    @ComponentScan("org.example.autoModel.model")
    public class MyBeanConfig {
    }

    定義后置處理器

    在Spring中,我們可以在自己定義的后置處理器BeanFactoryPostProcessor,獲取到對應的BeanDefinition。
    相信大家在學習Spring的時候有了解過BeanDefinition,不熟悉的可以搜索下BeanDefinition的概念,如果閱讀過Spring的源碼的話,對BeanDefinition應該就更加熟悉了。這里就不做過多的解釋了,后面在解讀Spring源碼的時候應該也會涉及到這部分的知識。
    簡單的來說,就是一個對象被注入到Spring中,實際是被解析成BeanDefinition對象,里面保存了各種需要用到的信息,并且可以在后置處理器中獲取到對應的BeanDefinition對象,然后對其做一些操作。

    @Slf4j(topic = "e")
    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition("student");
    //        beanDefinition.setAutowireMode(3);
            log.debug("mode:{}",beanDefinition.getAutowireMode());
        }
    }

    上面代碼所示,我們可以獲取這個beanDefinition在Spring容器中對應的autowireMode的值,并且可以修改這個autowireMode的值,來觀察下注入模型的改變,對bean的注入方式有什么影響。

    定義測試方法

    @Test
    public void modelTest(){
       AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
       context.register(MyBeanConfig.class);
       context.register(MyBeanFactoryPostProcessor.class);
       context.refresh();
       Student student = context.getBean(Student.class);
       student.showAddress();
    }

    執行測試方法,得出如下的結果。

    Spring注入模型怎么應用

    如上面所示,我們可以得到對應的autowireMode的值是0,并且是執行了Student的默認構造方法,由于沒有將address屬性注入到student中,所在調用address對應的方法的時候,拋出了空指針的異常。
    針對上面的對象,我們可以簡單分析下:

    • Spring默認的注入模型是0

    • 注入模型是0,意味著執行默認的構造方法,并且不會執行set方法去進行注入address這個對象,所以拋出了空指針異常

    我們可以在后置處理器中,修改對應autowioreMode的值,將autowireMode的值修改成1。

    beanDefinition.setAutowireMode(1);

    然后執行該測試方法,得到下面的結果。

    Spring注入模型怎么應用

    可以看到我們將注入模型的值修改成1,之后,spring就會通過set方法,將address注入到student中,就可以成功調用address的方法了。
    當然,我們將注入模型的值修改成2,也是注入成功的,并且也是通過set方法,只不過是byType和byName的區別。這個同學們可以自己嘗試下。
    下面,我們將注入模型的值修改成3來看下執行的結果。

    beanDefinition.setAutowireMode(3);

    結果如下:

    Spring注入模型怎么應用

    可以看到,如果將注入模型的值修改成了3,那么Spring是通過帶參的構造方法來注入給student的。
    通過上面簡單的例子,我們就可以了解到注入模型autowireMode對注入方式的影響,這為我們以后閱讀Spring的源碼打下了基礎。

    自動注入和手動注入

    上面我們將autowireMode值修改成1、2、3,就可以完成屬性的自動注入。那如果我們不去修改autowireMode的值,而是使用注解來將屬性注入到student中,會是怎樣的結果呢?
    我們來看下面的代碼:

    @Component
    @Slf4j
    public class Student {
    
        @Autowired
        private Address address;
    
        public Student(){
            log.info("default constructor...");
        }
    
        public Student(Address address){
            log.info("constructor inject...{}", address);
            this.address = address;
        }
    
        public void setAddress(Address address){
            log.info("setter...{}", address);
            this.address = address;
        }
    
        public void showAddress(){
            this.address.info();
        }
    }
    @Slf4j(topic = "e")
    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition("student");
    //        beanDefinition.setAutowireMode(3);
            log.debug("mode:{}",beanDefinition.getAutowireMode());
        }
    }

    查看結果

    Spring注入模型怎么應用

    我們發現使用@Autowired注解注入屬性的時候,注入模型的值是0,也就是默認的值。
    對于@Autowired的注解,我的看法是,使用注解注入屬性是手動注入的方式,Spring提供自動注入的方式只有set方法以及帶參的構造方法。而注解的注入方式,只不過是xml手動注入的一種簡化,Spring內部處理的機制都是類似的。
    了解過xml配置的同學大概有些印象,我們需要指定bean中屬性所對應的類的全路徑。而使用自動注入,我們可以指定byType或者byName。由于xml方式太久沒用了,大概就是這么個意思吧。
    所以我認為@Autowired注入的方式,不是自動注入,而是手動注入,只不過Spring容器內部幫我們處理了。

    以上就是“Spring注入模型怎么應用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    龙海市| 吴江市| 达州市| 裕民县| 出国| 克拉玛依市| 托克逊县| 同仁县| 吉首市| 满洲里市| 塔河县| 香河县| 石阡县| 涪陵区| 关岭| 彭泽县| 两当县| 繁峙县| 宜都市| 鄯善县| 盐山县| 北安市| 安仁县| 凤庆县| 三原县| 那曲县| 庆城县| 元江| 尼勒克县| 盐池县| 会东县| 嘉祥县| 梅河口市| 吴桥县| 城口县| 镇巴县| 邻水| 沛县| 建水县| 莆田市| 阿拉善左旗|