最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring IoC 容器的使用詳解(最新整理)

 更新時(shí)間:2025年07月02日 15:16:24   作者:2的n次方_  
文章介紹了Spring框架中的應(yīng)用分層思想與IoC容器原理,通過(guò)分層解耦業(yè)務(wù)邏輯、數(shù)據(jù)訪問等模塊,IoC容器利用@Component注解管理Bean,實(shí)現(xiàn)依賴注入與動(dòng)態(tài)獲取,本文給大家介紹Spring IoC 容器的使用詳解,感興趣的朋友一起看看吧

1. 應(yīng)用分層

應(yīng)用分層是一種軟件開發(fā)設(shè)計(jì)思想,它將應(yīng)用程序分成 N 個(gè)層次,這 N 個(gè)層次分別負(fù)責(zé)各自的職責(zé),多個(gè)層次之間協(xié)同提供完整的功能,根據(jù)項(xiàng)目的復(fù)雜度,可以分成三層,四層或更多層,MVC 就是把整體的程序分成了 Model(模型), View(視圖), Controller(控制器)三個(gè)層次

由于后端開發(fā),不需要過(guò)多的關(guān)注前端,所以又有了一種分層架構(gòu):把整體架構(gòu)分為表現(xiàn)層,業(yè)務(wù)邏輯層,數(shù)據(jù)層,又稱為“三層架構(gòu)”

  1. 表現(xiàn)層:用來(lái)展示數(shù)據(jù)結(jié)果和接收用戶指令,是最接近用戶的一層
  2. 業(yè)務(wù)邏輯層:負(fù)責(zé)處理業(yè)務(wù)邏輯,包含業(yè)務(wù)邏輯的具體實(shí)現(xiàn)
  3. 數(shù)據(jù)層:負(fù)責(zé)存儲(chǔ)和管理與應(yīng)用程序相關(guān)的數(shù)據(jù)

在 Spring 的實(shí)現(xiàn)中可以分為下面三個(gè)部分:

Controller:控制層。接收前端發(fā)送的請(qǐng)求,對(duì)請(qǐng)求進(jìn)行處理,并響應(yīng)數(shù)據(jù)

Service:業(yè)務(wù)邏輯層。處理具體的業(yè)務(wù)邏輯

Dao:數(shù)據(jù)訪問層,也被稱為持久層。負(fù)責(zé)數(shù)據(jù)訪問,操作(增刪查改)

2. IoC 的介紹

IoC:也就是控制反轉(zhuǎn)

Spring IoC 是一種設(shè)計(jì)模式,用于解耦對(duì)象之間的依賴關(guān)系,在之前創(chuàng)建的項(xiàng)目中對(duì)象通常會(huì)主動(dòng)創(chuàng)建和管理自己所依賴的對(duì)象,例如,一個(gè)UserService類可能會(huì)在自己的內(nèi)部使用new關(guān)鍵字來(lái)創(chuàng)建一個(gè)UserRepository對(duì)象用于數(shù)據(jù)訪問,這樣設(shè)計(jì)看似沒有問題,但是可維護(hù)性卻很低,當(dāng)有很多類創(chuàng)建了各自的對(duì)象時(shí),并且這些對(duì)象之間還有依賴關(guān)系,例如創(chuàng)建 Car ,F(xiàn)ramework,Bottom,Tire 類,從左到右依次存在依賴關(guān)系,當(dāng)其中有一個(gè)類的底層代碼改變之后,調(diào)用鏈上的代碼都需要修改

public class NewCarExample {
    public static void main(String[] args) {
        Car car = new Car(20);
        car.run();
    }
    //Car類
    static class Car {
        private Framework framework;
        public Car(int size) {
            framework = new Framework(size);
            System.out.println("Car init....");
        }
        public void run(){
            System.out.println("Car run...");
        }
    }
    //車身類
    static class Framework {
        private Bottom bottom;
        public Framework(int size) {
            bottom = new Bottom(size);
            System.out.println("Framework init...");
        }
    }
    //底盤類
    static class Bottom {
        private Tire tire;
        public Bottom(int size) {
            this.tire = new Tire(size);
            System.out.println("Bottom init...");
        }
    }
    //輪胎類
    static class Tire {
        // 尺?
        private int size;
        public Tire(int size){
            this.size = size;
            System.out.println("輪胎尺?:" + size);
        }
    }
}

修改輪胎的構(gòu)造方法之后,底盤也需要修改,當(dāng)修改底盤之后,上層調(diào)用也需要修改

而在 IoC 模式下,對(duì)象的創(chuàng)建和管理這些控制權(quán)被反轉(zhuǎn)了,不再由對(duì)象自身來(lái)控制,而是交給外部的容器(IoC 容器)來(lái)管理,下面演示一下使用 IoC 的思想來(lái)管理對(duì)象

public class IocCarExample {
    public static void main(String[] args) {
        Tire tire = new Tire(20);
        Bottom bottom = new Bottom(tire);
        Framework framework = new Framework(bottom);
        Car car = new Car(framework);
        car.run();
    }

通過(guò)這樣的形式,各個(gè)組件的依賴關(guān)系就發(fā)生了反轉(zhuǎn),統(tǒng)一對(duì)對(duì)象進(jìn)行管理,誰(shuí)需要這個(gè)對(duì)象直接傳過(guò)去一個(gè)對(duì)象,不需要他自己調(diào)用方法進(jìn)行創(chuàng)建

IoC 容器的工作就是把這些對(duì)象進(jìn)行統(tǒng)一管理

通過(guò)這種方式進(jìn)行資源的統(tǒng)一管理,在創(chuàng)建實(shí)例時(shí)不需要了解其中的細(xì)節(jié),降低了使用資源雙方的依賴程度

3. IoC 容器的使用

3.1. bean 的存儲(chǔ)

如果想要把一個(gè)對(duì)象交給 IoC 容器來(lái)管理,需要在類上添加一個(gè) @Component 注解,此外還有其它的一些注解可以實(shí)現(xiàn):

  1. 類注解:@Controller、@Service@Repository、@Component、@Configuration.
  2. 方法注解:@Bean.
@Controller
public class UserController {
    public void say(){
        System.out.println("UserController");
    }
}
@SpringBootApplication
public class SpringIoCApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(SpringIoCApplication.class, args);
        UserController bean = context.getBean(UserController.class);
        bean.say();
    }
}

ApplicationContext 可以理解為 Spring 的上下文,這個(gè)上下文就是指當(dāng)前的運(yùn)行環(huán)境和其他功能,也可以看作是一個(gè)容器,容器中存儲(chǔ)了很多內(nèi)容,這些內(nèi)容是當(dāng)前的運(yùn)行環(huán)境

之后就可以通過(guò)拿到的 context 來(lái)獲取 bean,關(guān)于獲取 bean 有多種方式:

Object getBean(String var1) throws BeansException;

根據(jù)bean名稱獲取bean

T getBean(String var1, Class var2) throws BeansException;

根據(jù)bean名稱和類型獲取bean

T getBean(Class var1) throws BeansException;

根據(jù)類型獲取bean

Object getBean(String var1, Object... var2) throws BeansException

按bean名稱和構(gòu)造函數(shù)參數(shù)動(dòng)態(tài)創(chuàng)建bean,只適?于具有原型(prototype)作?域的bean

T getBean(Class var1, Object... var2) throws BeansException;

按bean類型和構(gòu)造函數(shù)參數(shù)動(dòng)態(tài)創(chuàng)建bean, 只適?于具有原型(prototype)作?域的 bean

根據(jù)類型獲取 bean 的話,如果存在多個(gè)相同類型的 bean 那么就不能確定具體要獲取的是哪個(gè) bean ,同理,如果只是根據(jù)名稱來(lái)獲取 bean,如果重名的話也是不能正確獲取到 bean 的,所以就有了第三種方式,同時(shí)根據(jù)類型和名稱來(lái)獲取 bean

上面這三種獲取 bean 的方式是比較常用的

關(guān)于 IoC 中 bean 的名稱轉(zhuǎn)化規(guī)則:

如果是 UserController 會(huì)被轉(zhuǎn)成 userController,如果是 UController 就還是 UController

UserController bean1 = (UserController) context.getBean("userController");
bean1.say();

由于是根據(jù)名稱來(lái)獲取 bean,所以獲取到的 bean 不確定是什么類型,會(huì)返回一個(gè) Object 類型,需要強(qiáng)轉(zhuǎn)一下

同時(shí)指定類型和名稱:

UserController bean2 = context.getBean("userController", UserController.class);
bean2.say();

把上面獲取的 bean ,打印一下,發(fā)現(xiàn)獲取的實(shí)例的地址是一樣的,由此可以知道,通過(guò)這種方式獲取對(duì)象是基于單例模式實(shí)現(xiàn)的

接下來(lái)演示一下 @Service 注解:

@Service
public class UserService {
    public void say(){
        System.out.println("UserService");
    }
}
UserService service = context.getBean(UserService.class);
service.say();

然后發(fā)現(xiàn)和上面一樣也是可以運(yùn)行的,其它的幾個(gè)類注解也是一樣的

那么為什么實(shí)現(xiàn)的功能一樣,還需要分這么多不同的注解,這個(gè)是和之前的應(yīng)用分層是對(duì)應(yīng)的,通過(guò)不同的類注解來(lái)了解當(dāng)前類的用途

@Controller:控制層,接受請(qǐng)求,對(duì)請(qǐng)求進(jìn)行處理,并進(jìn)行響應(yīng)

@Servie:業(yè)務(wù)邏輯層,處理具體的業(yè)務(wù)邏輯

@Repository:數(shù)據(jù)訪問層, 也稱為持久層,負(fù)責(zé)數(shù)據(jù)訪問操作

@Configuration:配置層,處理項(xiàng)目中的一些配置信息

3.2. 方法注解@Bean

上面四個(gè)注解都是 @Component的衍生注解

類注解是添加到某個(gè)類上的,但是存在兩個(gè)問題:

  1. 如果使用外部包里的類,沒辦法添加注解
  2. 同時(shí),由于類注解默認(rèn)創(chuàng)建的對(duì)象是單例對(duì)象,如果需要多個(gè)對(duì)象就需要調(diào)整

方法注解 @Bean就可以解決上述問題

例如,在一個(gè)外部包里有一個(gè) UserInfo 類

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserInfo {
    private String name;
    private Integer age;
}

可以通過(guò)在獲取對(duì)象的方法上加上@Bean

@Component
public class UserInfoComponent {
    @Bean
    public UserInfo userInfo(){
        return new UserInfo("zhangsan",20);
    }
}

如果說(shuō)需要?jiǎng)?chuàng)建對(duì)個(gè)對(duì)象的話:

這個(gè)問題就是在獲取 bean 的時(shí)候發(fā)現(xiàn)了具有相同類型的 bean,可以直接通過(guò)獲取 bean 的名稱,這里的名稱和方法注解下方法名是對(duì)應(yīng)的

UserInfo bean = (UserInfo) context.getBean("userInfo");
System.out.println(bean);

上面的注解,無(wú)論是類注解還是方法注解,都可以實(shí)現(xiàn)重命名

重命名之后就需要使用改之后的名字了

4. 掃描路徑

如果說(shuō)把啟動(dòng)類放到其他目錄下再運(yùn)行就會(huì)報(bào)錯(cuò),是因?yàn)樯厦娼榻B的注解如果想要生效,是需要配置掃描路徑的,默認(rèn)的掃描范圍是 Spring Boot 啟動(dòng)類所在的包和它的子包,可以通過(guò)@ComponentScan來(lái)配置掃描路徑

@ComponentScan源碼中,是支持傳入一個(gè)數(shù)組的,如果想要配置多個(gè)掃描路徑可以直接傳入一個(gè)數(shù)組

@ComponentScan({"com.example.service","com.example.controller"})

到此這篇關(guān)于SpringIoC 容器的使用的文章就介紹到這了,更多相關(guān)SpringIoC 容器使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實(shí)現(xiàn)Markdown轉(zhuǎn)為PDF的兩種方式

    Java實(shí)現(xiàn)Markdown轉(zhuǎn)為PDF的兩種方式

    文章介紹了兩種將Markdown轉(zhuǎn)換為PDF的方法:一是使用商業(yè)授權(quán)的Spire.Doc框架,操作簡(jiǎn)單但需要授權(quán);二是使用開源的Markdown到HTML再到PDF的轉(zhuǎn)換流程,需要自行實(shí)現(xiàn)轉(zhuǎn)換邏輯,需要的朋友可以參考下
    2026-01-01
  • Java中序列化和反序列化的完整講解

    Java中序列化和反序列化的完整講解

    序列化是將對(duì)象轉(zhuǎn)換成二進(jìn)制字節(jié)流的過(guò)程;反序列化是從二進(jìn)制字節(jié)流中恢復(fù)對(duì)象的過(guò)程。文中將為大家詳細(xì)講講二者的原理與實(shí)現(xiàn),需要的可以參考一下
    2022-11-11
  • logback.xml動(dòng)態(tài)配置程序路徑的操作

    logback.xml動(dòng)態(tài)配置程序路徑的操作

    這篇文章主要介紹了logback.xml動(dòng)態(tài)配置程序路徑的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • IDEA?2022最新激活碼注冊(cè)碼超詳細(xì)教程(親測(cè)激活有效)

    IDEA?2022最新激活碼注冊(cè)碼超詳細(xì)教程(親測(cè)激活有效)

    這篇文章主要介紹了IDEA?2022最新激活碼超詳細(xì)教程(親測(cè)激活至2099年),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • java實(shí)現(xiàn)多數(shù)據(jù)源切換方式

    java實(shí)現(xiàn)多數(shù)據(jù)源切換方式

    本文介紹實(shí)現(xiàn)多數(shù)據(jù)源切換的四步方法:導(dǎo)入依賴、配置文件、啟動(dòng)類注解、使用@DS標(biāo)記mapper和服務(wù)層,通過(guò)注解實(shí)現(xiàn)數(shù)據(jù)源動(dòng)態(tài)切換,適用于實(shí)際開發(fā)中的多數(shù)據(jù)源場(chǎng)景
    2025-08-08
  • Java 實(shí)戰(zhàn)項(xiàng)目錘煉之嘟嘟健身房管理系統(tǒng)的實(shí)現(xiàn)流程

    Java 實(shí)戰(zhàn)項(xiàng)目錘煉之嘟嘟健身房管理系統(tǒng)的實(shí)現(xiàn)流程

    讀萬(wàn)卷書不如行萬(wàn)里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SSM+jsp+mysql+maven實(shí)現(xiàn)一個(gè)健身房管理系統(tǒng),大家可以在過(guò)程中查缺補(bǔ)漏,提升水平
    2021-11-11
  • Java實(shí)現(xiàn)簡(jiǎn)單的酒店管理系統(tǒng)

    Java實(shí)現(xiàn)簡(jiǎn)單的酒店管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)酒店管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • Spring?Boot實(shí)現(xiàn)熱部署的五種方式

    Spring?Boot實(shí)現(xiàn)熱部署的五種方式

    這篇文章主要介紹了Spring?Boot?五種熱部署方式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-01-01
  • SpringBoot中Dozer的使用小結(jié)

    SpringBoot中Dozer的使用小結(jié)

    dozer是用來(lái)兩個(gè)對(duì)象之間屬性轉(zhuǎn)換的工具,有了這個(gè)工具之后,我們將一個(gè)對(duì)象的所有屬性值轉(zhuǎn)給另一個(gè)對(duì)象時(shí),就不需要再去寫重復(fù)的set和get方法了,下面介紹下SpringBoot中Dozer的使用,感興趣的朋友一起看看吧
    2022-03-03
  • Spring溫故而知新系列教程之AOP代理

    Spring溫故而知新系列教程之AOP代理

    Spring AOP 是代理模式的應(yīng)用,可以使用JDK提供的Proxy類或通過(guò)字節(jié)碼增強(qiáng)來(lái)實(shí)現(xiàn)。下面這篇文章主要給大家介紹了關(guān)于Spring之AOP代理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-05-05

最新評(píng)論

门源| 杨浦区| 南宁市| 东安县| 大理市| 乌鲁木齐市| 安平县| 涿州市| 都江堰市| 沙坪坝区| 台北县| 灌云县| 突泉县| 许昌县| 洛川县| 丹江口市| 晋州市| 安乡县| 万源市| 郧西县| 龙胜| 汤原县| 阳新县| 嘉鱼县| 德庆县| 大竹县| 禹州市| 霍山县| 临泉县| 武川县| 民丰县| 峨眉山市| 荣昌县| 文成县| 汉寿县| 洞头县| 星座| 同仁县| 黔西县| 兴国县| 基隆市|