欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

1. 應用分層

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

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

  1. 表現層:用來展示數據結果和接收用戶指令,是最接近用戶的一層
  2. 業(yè)務邏輯層:負責處理業(yè)務邏輯,包含業(yè)務邏輯的具體實現
  3. 數據層:負責存儲和管理與應用程序相關的數據

在 Spring 的實現中可以分為下面三個部分:

Controller:控制層。接收前端發(fā)送的請求,對請求進行處理,并響應數據

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

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

2. IoC 的介紹

IoC:也就是控制反轉

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

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);
        }
    }
}

修改輪胎的構造方法之后,底盤也需要修改,當修改底盤之后,上層調用也需要修改

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

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();
    }

通過這樣的形式,各個組件的依賴關系就發(fā)生了反轉,統一對對象進行管理,誰需要這個對象直接傳過去一個對象,不需要他自己調用方法進行創(chuàng)建

IoC 容器的工作就是把這些對象進行統一管理

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

3. IoC 容器的使用

3.1. bean 的存儲

如果想要把一個對象交給 IoC 容器來管理,需要在類上添加一個 @Component 注解,此外還有其它的一些注解可以實現:

  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 的上下文,這個上下文就是指當前的運行環(huán)境和其他功能,也可以看作是一個容器,容器中存儲了很多內容,這些內容是當前的運行環(huán)境

之后就可以通過拿到的 context 來獲取 bean,關于獲取 bean 有多種方式:

Object getBean(String var1) throws BeansException;

根據bean名稱獲取bean

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

根據bean名稱和類型獲取bean

T getBean(Class var1) throws BeansException;

根據類型獲取bean

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

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

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

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

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

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

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

如果是 UserController 會被轉成 userController,如果是 UController 就還是 UController

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

由于是根據名稱來獲取 bean,所以獲取到的 bean 不確定是什么類型,會返回一個 Object 類型,需要強轉一下

同時指定類型和名稱:

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

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

接下來演示一下 @Service 注解:

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

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

那么為什么實現的功能一樣,還需要分這么多不同的注解,這個是和之前的應用分層是對應的,通過不同的類注解來了解當前類的用途

@Controller:控制層,接受請求,對請求進行處理,并進行響應

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

@Repository:數據訪問層, 也稱為持久層,負責數據訪問操作

@Configuration:配置層,處理項目中的一些配置信息

3.2. 方法注解@Bean

上面四個注解都是 @Component的衍生注解

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

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

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

例如,在一個外部包里有一個 UserInfo 類

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

可以通過在獲取對象的方法上加上@Bean

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

如果說需要創(chuàng)建對個對象的話:

這個問題就是在獲取 bean 的時候發(fā)現了具有相同類型的 bean,可以直接通過獲取 bean 的名稱,這里的名稱和方法注解下方法名是對應的

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

上面的注解,無論是類注解還是方法注解,都可以實現重命名

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

4. 掃描路徑

如果說把啟動類放到其他目錄下再運行就會報錯,是因為上面介紹的注解如果想要生效,是需要配置掃描路徑的,默認的掃描范圍是 Spring Boot 啟動類所在的包和它的子包,可以通過@ComponentScan來配置掃描路徑

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

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

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

相關文章

  • SpringSecurity rememberme功能實現過程解析

    SpringSecurity rememberme功能實現過程解析

    這篇文章主要介紹了SpringSecurity rememberme功能實現過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • SpringBoot集成ENC對配置文件進行加密的流程步驟

    SpringBoot集成ENC對配置文件進行加密的流程步驟

    Spring Boot Encoder,即Spring Boot加密模塊,它提供了一種簡單的方式來集成安全編碼功能到Spring Boot應用程序中,它是Spring Security框架的一部分,旨在幫助開發(fā)者輕松地處理數據加密,本文給大家介紹了SpringBoot集成ENC對配置文件進行加密的流程步驟
    2024-12-12
  • 如何將字符串、字節(jié)數組轉為輸入流

    如何將字符串、字節(jié)數組轉為輸入流

    這篇文章主要介紹了如何將字符串、字節(jié)數組轉為輸入流問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java用BigDecimal類解決Double類型精度丟失的問題

    Java用BigDecimal類解決Double類型精度丟失的問題

    這篇文章主要介紹了Java用BigDecimal類解決Double類型精度丟失的問題,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-12-12
  • Spring Boot 中PageHelper 插件使用配置思路詳解

    Spring Boot 中PageHelper 插件使用配置思路詳解

    這篇文章主要介紹了Spring Boot 中PageHelper 插件使用配置及實現思路,通過引入myabtis和pagehelper依賴,在yml中配置mybatis掃描和實體類,具體實現方法跟隨小編一起看看吧
    2021-08-08
  • springboot?jpa之返回表中部分字段的處理詳解

    springboot?jpa之返回表中部分字段的處理詳解

    這篇文章主要介紹了springboot?jpa之返回表中部分字段的處理詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java8中Stream的使用以及分割list案例

    java8中Stream的使用以及分割list案例

    這篇文章主要介紹了java8中Stream的使用以及分割list案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • IDEA實現遠程調試步驟詳解

    IDEA實現遠程調試步驟詳解

    這篇文章主要介紹了IDEA實現遠程調試步驟詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • java使用JWT的方法

    java使用JWT的方法

    這篇文章主要介紹了java使用JWT的方法,JWT是token的一種,一個JWT字符串包含三個部分分別是Header、Payload和Signature,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-06-06
  • Jmeter內置變量vars和props的使用詳解

    Jmeter內置變量vars和props的使用詳解

    JMeter是一個功能強大的負載測試工具,它提供了許多有用的內置變量來支持測試過程,其中最常用的變量是 vars 和 props,本文通過代碼示例詳細給大家介紹了Jmeter內置變量vars和props的使用,需要的朋友可以參考下
    2024-08-08

最新評論