亚欧色一区w666天堂,色情一区二区三区免费看,少妇特黄A片一区二区三区,亚洲人成网站999久久久综合,国产av熟女一区二区三区

  • 發布文章
  • 消息中心
點贊
收藏
評論
分享
原創

Spring框架核心——基于IDEA實現IoC(一)

2022-11-29 00:46:40
39
0

0.引言

大家可能不知道什么是IoC,但(dan)只要(yao)你(ni)接(jie)觸過Java,多多少(shao)少(shao)都會接(jie)觸到(dao)Spring框架,比如用于(yu)web開(kai)發(fa)的Spring MVC、持久層開(kai)發(fa)的Spring Data、微服務開(kai)發(fa)Spring Cloud,以及經典的“輪(lun)子(zi)的輪(lun)子(zi),框架的框架”——Spring Boot。我(wo)們把(ba)這一大坨東(dong)西就(jiu)叫(jiao)做Spring全家桶。

今天給大家介紹的,就是(shi)spring全家桶中相當基礎的概(gai)念:IoC

本文我(wo)們簡單的介紹下概念以及實(shi)現方(fang)法,后(hou)面有機會來分(fen)(fen)享高階應用以及源碼分(fen)(fen)析(xi)

1 什么是IoC?為什么要用IoC?

IoC,即控制(zhi)反轉——是Spring全家(jia)桶各個功能模塊的基礎(chu)

每個功能模塊都依賴于對象而發揮作用,IoC的本質就是幫助創建對象

↑↑↑ 這句(ju)話聽起來真的迷惑,創建對(dui)象還要(yao)幫助(zhu)?那我不是要(yao)多(duo)少就new多(duo)少?

能(neng)有這個(ge)疑惑的(de)讀者,可能(neng)跟我一樣年輕,沒咋改(gai)過那種(zhong)耦合度很高的(de)代碼。尤其(qi)是現在利用(yong)spring開(kai)發的(de)絕大(da)部分大(da)型工(gong)程,耦合度都很高。

舉個(ge)簡單的(de)例(li)子:在業務層,我(wo)定義了一(yi)(yi)個(ge)類,比如說是用來計(ji)算(suan)某個(ge)幾何圖形的(de)屬性,里(li)面(mian)可能有計(ji)算(suan)面(mian)積啊(a)(a)、計(ji)算(suan)周(zhou)長啊(a)(a)這(zhe)些(xie)方法。同時肯定會有一(yi)(yi)個(ge)實例(li)化的(de)圖形類對象,我(wo)們(men)就叫他(ta)diagram。那你寫出(chu)來可能就是下面(mian)這(zhe)樣:

private Diagram diagram = new Diagram( );

這個(ge)業務層的類(lei)(lei)比如定(ding)義為DiagramService0,那(nei)定(ding)義Diagram這個(ge)類(lei)(lei)的數據層就(jiu)被(bei)DiagramService0調(diao)用了(le)。一些大型(xing)的工程里,我們(men)極有可能寫了(le)Diagram這個(ge)類(lei)(lei),運用到(dao)很多地方,可能不僅(jin)僅(jin)是(shi)DiagramService0。

也許換個(ge)(ge)使用(yong)場(chang)景,比如我又需(xu)(xu)要(yao)算圖(tu)形有幾個(ge)(ge)內角,但是這個(ge)(ge)需(xu)(xu)求又只在某個(ge)(ge)場(chang)景用(yong)得(de)上。那我是不是沒必要(yao)專(zhuan)門(men)把這個(ge)(ge)功能集(ji)成到DiagramService0,更好的辦法顯然(ran)是寫一個(ge)(ge)繼(ji)承(cheng)類,比如說是DiagramService1。

如果有一天,Diagram這個(ge)類要(yao)(yao)升級要(yao)(yao)迭代(dai)(就比(bi)如最簡單的改名,改成DiagramNew),我們就需要(yao)(yao)去維(wei)護(hu)DiagramService0、DiagramService1。這只是(shi)一個(ge)簡單的例子,事(shi)實上你(ni)需要(yao)(yao)維(wei)護(hu)的東(dong)西在工程的方(fang)方(fang)面(mian)面(mian),非常的不方(fang)便。

那怎么解決呢?

——是不是我們可(ke)(ke)以考慮,不由(you)自己主動(dong)去new對(dui)象(xiang),交(jiao)給外部來(lai)創(chuang)建(jian)對(dui)象(xiang)。不管我的(de)類怎么(me)迭代,它(ta)只(zhi)要按照我寫的(de)這個類去對(dui)應的(de)地(di)方創(chuang)建(jian)對(dui)象(xiang)就可(ke)(ke)以了(le)

這就是控制反轉的核心,我們把對象創建的權利,從我們的程序轉移到外部,從而解(jie)決我們在開發中(zhong)修(xiu)改(gai)一(yi)處(chu)代(dai)碼(ma),往往要連帶著修(xiu)改(gai)很多關聯代(dai)碼(ma)的問題。這個(ge)外部,就是我們的IoC容器(對,IoC的本(ben)質就是一(yi)個(ge)容器)

學術一(yi)點的(de)說(shuo):IOC容器(qi)負責(ze)對象(xiang)的(de)創建、初始化等一(yi)系(xi)列工作,被(bei)(bei)創建或(huo)被(bei)(bei)管理的(de)對象(xiang)在IOC容器(qi)中統稱為Bean

2 如何實現IoC

其實上實現IoC的辦法并不少,比較常用的就有:1.基于注解(jie)(jie) 2.基于xml文(wen)件 3.掃包+注解(jie)(jie)

這里我們只介紹第三種方法,因為它最簡單,不再需要xml與配置類,直接在目標類創建。
1.我們先在IDEA建立一個SpringBoot項目(本質上也是maven項目),這樣就不用特意引入一些spring的依賴了,這個過程很簡單就不展示了
2.先創建一個domian包,放一個User類用來做測試,隨便定義了uid/uname/password/addrs四個參數
注意:這里是用了lombok所以沒寫get set方法,這個東西侵入性有點強,有些項目是不讓用的
package wy.springboot01.domain;

import lombok.Data;
import org.springframework.stereotype.Component;

import java.util.ArrayList;

/**
 * springboot項目啟動的時候,自動將application.yml內容加載到實體對象中
 */

@Data
//將實體類交給spring管理,自動掃描
@Component
public class User {
    private Integer uid;
    private String uname;
    private String password;
    private ArrayList<String> addrs;
}
3 .創建一個包用來放IoC的代碼,這里就叫IoC好了,引入剛剛的User類,就新建一個IoCTest類,讓main方法生成一個User對象好了
package wy.springboot01.IoC;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import wy.springboot01.domain.User;

public class IoCTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("wy.springboot01.domain");
        //context.getBean(User.class)利用IoC生成對象
        System.out.println(context.getBean(User.class));
    }
}
4.好了,我們直接運行這個IoCTest的main方法,會輸出什么呢?是如下的結果:
User(uid=null, uname=null, password=null, addrs==null)
很顯然context.getBean(User.class)成功的創建了對象并sout了出來!有了它我們就不用擔心User類的迭代會影響到其他代碼了

3 對IoC創建對象的參數進行賦值

當然,如果你將這(zhe)(zhe)個(ge)(ge)IoC創建的User對象保存下來,就(jiu)可(ke)以用set對這(zhe)(zhe)些參(can)數進行賦值(zhi),但是我們往(wang)往(wang)喜歡給他(ta)們來上一個(ge)(ge)默(mo)認值(zhi),怎么做呢?

方法一:在參(can)數(shu)上加@Value注解(jie)

這種方(fang)法非常簡單,如下:

@Data
//將實體類交給spring管理,自動掃描
@Component
public class User {
    @Value("132456")
    private Integer uid;
    @Value("wy")
    private String uname;
    @Value("asd")
    private String password;
    @Value("Beijing, Sichuan, Nanchang")
    private List<String> addrs;

    public User() {
    }

    public User(Integer uid, String uname, String password, ArrayList<String> addrs) {
        this.uid = uid;
        this.uname = uname;
        this.password = password;
        this.addrs = addrs;
    }
}

方(fang)法(fa)二:導入(ru)一個配置類

通(tong)常我們還是推(tui)薦這(zhe)個方法,如(ru)下更改代(dai)碼(ma):

package wy.springboot01.domain;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.ArrayList;

/**
 * springboot項目啟動的時候,自動將application.yml內容加載到實體對象中
 */

@Data
//將實體類交給spring管理,自動掃描
@Component
//加載配置內容,設定配置前綴,注意:prefix參數不支持小駝峰原則,必須全部小寫
@ConfigurationProperties(prefix = "user")
public class User {
    private Integer uid;
    private String uname;
    private String password;
    private ArrayList<String> addrs;

    public User() {
    }

    public User(Integer uid, String uname, String password, ArrayList<String> addrs) {
        this.uid = uid;
        this.uname = uname;
        this.password = password;
        this.addrs = addrs;
    }
}

顯然我們通過@ConfigurationProperties這個注解去加載了配置類,我們只需要在與java這個路徑平行的resources路徑下新增一個yml文件當做配置即可,比如我們就叫做application.yml(通常這個路徑會有一個默認的application.properties,但我習慣了用yml做配置這里就不寫application.properties做配置的方法了,其實也很簡單感興趣的可以自行去搜索一下),我們這么來配置它(一定要注意冒號后面的空格)

#配置屬性并加載到User實體中
user:
  uid: 1546879
  uname: wuyu
  password: wuyu1999
  addrs:
    - Beijing
    - Sichuan
    - Nanchang

可以看到我們的前綴叫做user,所以我們在User中使用@ConfigurationProperties注解時,參數要填 prefix="user"。這么一來,這些默認值就會在運行的時候被加載進去,此時如果你再次運行IoCTest,就會輸出有上述值的對象(需要注意的是,很多時候IoC創建對象這種方式有可能不生效,還是建議使用@Value)

還有一種特殊情況:如果一個類的參數包含了另一個類的對象,這個時候我們就要用到依賴注入@Autowired:

@Data
//將實體類交給spring管理,自動掃描
@Component
public class SuperUser {
    @Value(“777”)
    private String info1;
    @Value(“666”)
    private String info2;
    @Autowired
    private User user;
}

 當(dang)時(shi)我試到這一(yi)步的時(shi)候(hou)產生了(le)一(yi)個疑問(wen),有的時(shi)候(hou)我們為(wei)了(le)好區(qu)分或者說為(wei)了(le)好給讀代碼的人(ren)信(xin)息,可能我這個User類在注入Bean的時(shi)候(hou)(即@Component這一(yi)步)我會加一(yi)些參(can)數,打個比方我會寫成(cheng)@Component("ctyunUser"),那這個User類注入到bean里面的名(ming)稱(cheng)就叫ctyunUser。

這個時候我的SuperUser的user參數還找不找得到User這個類呢?大家可以自己去試一下,實際上是找的到的,因為@Autowired是默認使用參數的類型去找,在這(zhe)個(ge)例子(zi)里他是默認去找Bean中有沒有User這(zhe)個(ge)類,實際上是有的(de)只不過它的(de)別名(ming)叫做ctyunUser。

如果我們要用名稱去找,就需要在@Autowired下面再加一個@Qualifier(“ctyunUser”),這樣他就會根據名稱去找,如果這個時候User的@Component的參數沒有寫或寫的不是ctyunUser,創建對象就會報錯

這(zhe)一(yi)塊大家可以自己去試一(yi)試,還是挺有意思的

 


以上就(jiu)是(shi)IoC非常初(chu)級的(de)一個用(yong)法,下一篇我們會(hui)介紹一些進(jin)階的(de)用(yong)法和更多有趣的(de)案例

0條評論
0 / 1000
才開始學技術的小白
23文章數
2粉絲數
才開始學技術的小白
23 文章(zhang) | 2 粉絲
原創

Spring框架核心——基于IDEA實現IoC(一)

2022-11-29 00:46:40
39
0

0.引言

大家(jia)可能不知道什么是IoC,但(dan)只要(yao)你接(jie)觸過Java,多多少少都會接(jie)觸到Spring框架(jia),比(bi)如(ru)用于(yu)web開發(fa)的(de)Spring MVC、持(chi)久(jiu)層開發(fa)的(de)Spring Data、微服務(wu)開發(fa)Spring Cloud,以(yi)及經典的(de)&ldquo;輪(lun)子的(de)輪(lun)子,框架(jia)的(de)框架(jia)”——Spring Boot。我們把(ba)這一大坨(tuo)東西就(jiu)叫做(zuo)Spring全家(jia)桶。

今天給大家介紹的(de),就是spring全(quan)家桶中相當基(ji)礎的(de)概念(nian):IoC

本文我們(men)簡單的介紹(shao)下概念以(yi)(yi)及實現方法,后面有機會來(lai)分享高階應用以(yi)(yi)及源碼(ma)分析

1 什(shen)(shen)么是IoC?為什(shen)(shen)么要用IoC?

IoC,即控制(zhi)反轉——是(shi)Spring全家桶各(ge)個功能模塊的(de)基礎

每個功能模塊都依賴于對象而發揮作用,IoC的本質就是幫助創建對象

↑↑↑ 這(zhe)句話聽起來真(zhen)的迷惑,創(chuang)建對象還(huan)要(yao)幫助?那我不是要(yao)多少就new多少?

能有(you)這個疑(yi)惑的(de)讀者,可能跟(gen)我一樣年(nian)輕,沒咋改(gai)過那種(zhong)耦(ou)(ou)合度(du)很(hen)高的(de)代碼。尤(you)其是(shi)現在利用spring開(kai)發(fa)的(de)絕大(da)部分大(da)型工程,耦(ou)(ou)合度(du)都(dou)很(hen)高。

舉個簡單的(de)(de)例(li)子:在業務層,我(wo)定義了(le)一個類,比如說是(shi)用(yong)來計(ji)算某個幾何圖(tu)形(xing)的(de)(de)屬(shu)性,里(li)面可能(neng)有(you)計(ji)算面積啊、計(ji)算周長啊這(zhe)些(xie)方法。同時肯定會有(you)一個實例(li)化的(de)(de)圖(tu)形(xing)類對(dui)象,我(wo)們就(jiu)叫(jiao)他diagram。那你寫出來可能(neng)就(jiu)是(shi)下面這(zhe)樣:

private Diagram diagram = new Diagram( );

這(zhe)個(ge)(ge)業務層的類比如定(ding)(ding)義為(wei)DiagramService0,那定(ding)(ding)義Diagram這(zhe)個(ge)(ge)類的數據層就被DiagramService0調用(yong)了。一些大(da)型的工程里,我們極有可(ke)能寫了Diagram這(zhe)個(ge)(ge)類,運用(yong)到很多地方,可(ke)能不僅(jin)僅(jin)是DiagramService0。

也許換(huan)個(ge)使用場景,比如我又需要算圖形有幾個(ge)內角,但是這(zhe)個(ge)需求又只(zhi)在某個(ge)場景用得上。那我是不是沒必要專門把這(zhe)個(ge)功能集成到DiagramService0,更好的(de)辦法顯然是寫一個(ge)繼承類,比如說是DiagramService1。

如(ru)果有一天,Diagram這個類(lei)要(yao)升級要(yao)迭代(就比如(ru)最簡單的(de)改(gai)(gai)名,改(gai)(gai)成(cheng)DiagramNew),我們(men)就需(xu)(xu)要(yao)去維護DiagramService0、DiagramService1。這只是一個簡單的(de)例子,事(shi)實(shi)上(shang)你需(xu)(xu)要(yao)維護的(de)東西在工(gong)程的(de)方方面(mian)(mian)面(mian)(mian),非常的(de)不(bu)方便(bian)。

那怎么解決呢?

——是(shi)(shi)不(bu)是(shi)(shi)我(wo)(wo)們可以考慮,不(bu)由自己主動去new對(dui)象(xiang),交給外部來創(chuang)建對(dui)象(xiang)。不(bu)管我(wo)(wo)的(de)(de)類怎么迭(die)代,它只要按照我(wo)(wo)寫(xie)的(de)(de)這個(ge)類去對(dui)應的(de)(de)地方創(chuang)建對(dui)象(xiang)就(jiu)可以了

這就是控制反轉的核心,我們把對象創建的權利,從我們的程序轉移到外部,從(cong)而解決我(wo)們在開發中修改(gai)一處代碼(ma),往往要連帶著修改(gai)很多(duo)關聯代碼(ma)的(de)(de)(de)問題。這個外部,就(jiu)是(shi)我(wo)們的(de)(de)(de)IoC容器(對,IoC的(de)(de)(de)本質就(jiu)是(shi)一個容器)

學術(shu)一(yi)點的說:IOC容器負責對象的創建、初(chu)始化(hua)等一(yi)系列工作,被創建或(huo)被管理的對象在IOC容器中統稱(cheng)為Bean

2 如何實現IoC

其實上實現IoC的辦法并不少,比較常用的就有:1.基于(yu)注解(jie) 2.基于(yu)xml文件 3.掃包+注解(jie)

這里我們只介紹第三種方法,因為它最簡單,不再需要xml與配置類,直接在目標類創建。
1.我們先在IDEA建立一個SpringBoot項目(本質上也是maven項目),這樣就不用特意引入一些spring的依賴了,這個過程很簡單就不展示了
2.先創建一個domian包,放一個User類用來做測試,隨便定義了uid/uname/password/addrs四個參數
注意:這里是用了lombok所以沒寫get set方法,這個東西侵入性有點強,有些項目是不讓用的
package wy.springboot01.domain;

import lombok.Data;
import org.springframework.stereotype.Component;

import java.util.ArrayList;

/**
 * springboot項目啟動的時候,自動將application.yml內容加載到實體對象中
 */

@Data
//將實體類交給spring管理,自動掃描
@Component
public class User {
    private Integer uid;
    private String uname;
    private String password;
    private ArrayList<String> addrs;
}
3 .創建一個包用來放IoC的代碼,這里就叫IoC好了,引入剛剛的User類,就新建一個IoCTest類,讓main方法生成一個User對象好了
package wy.springboot01.IoC;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import wy.springboot01.domain.User;

public class IoCTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("wy.springboot01.domain");
        //context.getBean(User.class)利用IoC生成對象
        System.out.println(context.getBean(User.class));
    }
}
4.好了,我們直接運行這個IoCTest的main方法,會輸出什么呢?是如下的結果:
User(uid=null, uname=null, password=null, addrs==null)
很顯然context.getBean(User.class)成功的創建了對象并sout了出來!有了它我們就不用擔心User類的迭代會影響到其他代碼了

3 對IoC創建對象的參數進行賦值

當然(ran),如果你將這(zhe)個(ge)IoC創建的User對(dui)象保存(cun)下來,就可以用set對(dui)這(zhe)些參數進行賦值(zhi),但(dan)是我(wo)們往(wang)往(wang)喜(xi)歡給他們來上一個(ge)默認值(zhi),怎(zen)么做(zuo)呢(ni)?

方(fang)法一:在參數上加@Value注解

這種方法非常簡單,如下:

@Data
//將實體類交給spring管理,自動掃描
@Component
public class User {
    @Value("132456")
    private Integer uid;
    @Value("wy")
    private String uname;
    @Value("asd")
    private String password;
    @Value("Beijing, Sichuan, Nanchang")
    private List<String> addrs;

    public User() {
    }

    public User(Integer uid, String uname, String password, ArrayList<String> addrs) {
        this.uid = uid;
        this.uname = uname;
        this.password = password;
        this.addrs = addrs;
    }
}

方法(fa)二(er):導入(ru)一個配置類

通(tong)常我們(men)還是推(tui)薦這個方法,如下更(geng)改代碼(ma):

package wy.springboot01.domain;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.ArrayList;

/**
 * springboot項目啟動的時候,自動將application.yml內容加載到實體對象中
 */

@Data
//將實體類交給spring管理,自動掃描
@Component
//加載配置內容,設定配置前綴,注意:prefix參數不支持小駝峰原則,必須全部小寫
@ConfigurationProperties(prefix = "user")
public class User {
    private Integer uid;
    private String uname;
    private String password;
    private ArrayList<String> addrs;

    public User() {
    }

    public User(Integer uid, String uname, String password, ArrayList<String> addrs) {
        this.uid = uid;
        this.uname = uname;
        this.password = password;
        this.addrs = addrs;
    }
}

顯然我們通過@ConfigurationProperties這個注解去加載了配置類,我們只需要在與java這個路徑平行的resources路徑下新增一個yml文件當做配置即可,比如我們就叫做application.yml(通常這個路徑會有一個默認的application.properties,但我習慣了用yml做配置這里就不寫application.properties做配置的方法了,其實也很簡單感興趣的可以自行去搜索一下),我們這么來配置它(一定要注意冒號后面的空格)

#配置屬性并加載到User實體中
user:
  uid: 1546879
  uname: wuyu
  password: wuyu1999
  addrs:
    - Beijing
    - Sichuan
    - Nanchang

可以看到我們的前綴叫做user,所以我們在User中使用@ConfigurationProperties注解時,參數要填 prefix="user"。這么一來,這些默認值就會在運行的時候被加載進去,此時如果你再次運行IoCTest,就會輸出有上述值的對象(需要注意的是,很多時候IoC創建對象這種方式有可能不生效,還是建議使用@Value)

還有一種特殊情況:如果一個類的參數包含了另一個類的對象,這個時候我們就要用到依賴注入@Autowired:

@Data
//將實體類交給spring管理,自動掃描
@Component
public class SuperUser {
    @Value(“777”)
    private String info1;
    @Value(“666”)
    private String info2;
    @Autowired
    private User user;
}

 當(dang)時(shi)我(wo)試到這一(yi)步(bu)的(de)時(shi)候(hou)產生了一(yi)個(ge)疑問(wen),有的(de)時(shi)候(hou)我(wo)們為(wei)了好區分或者說為(wei)了好給讀(du)代(dai)碼的(de)人信息,可能我(wo)這個(ge)User類(lei)在注(zhu)入Bean的(de)時(shi)候(hou)(即@Component這一(yi)步(bu))我(wo)會加(jia)一(yi)些參數,打(da)個(ge)比方我(wo)會寫成@Component("ctyunUser"),那這個(ge)User類(lei)注(zhu)入到bean里(li)面(mian)的(de)名(ming)稱就叫ctyunUser。

這個時候我的SuperUser的user參數還找不找得到User這個類呢?大家可以自己去試一下,實際上是找的到的,因為@Autowired是默認使用參數的類型去找,在這(zhe)個(ge)例子(zi)里(li)他是默認去(qu)找Bean中有沒有User這(zhe)個(ge)類,實際上是有的只不過它的別(bie)名叫做ctyunUser。

如果我們要用名稱去找,就需要在@Autowired下面再加一個@Qualifier(“ctyunUser”),這樣他就會根據名稱去找,如果這個時候User的@Component的參數沒有寫或寫的不是ctyunUser,創建對象就會報錯

這一(yi)塊(kuai)大家可以(yi)自己去試(shi)一(yi)試(shi),還是挺有(you)意思(si)的

 


以上就是IoC非(fei)常初級的一(yi)個用(yong)法,下一(yi)篇我們會介紹一(yi)些進(jin)階的用(yong)法和更多有趣的案(an)例(li)

文章來自個人專欄
文章 | 訂(ding)閱(yue)
0條評論
0 / 1000
請輸入你的評論
1
0