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

一文帶你了解Spring中存入Bean和獲取Bean的方式

 更新時(shí)間:2023年07月20日 09:50:14   作者:一個(gè)想打拳的程序員  
這篇文章主要帶大家了解Spring中存入Bean和獲取Bean的方式,文中的代碼示例講解的非常詳細(xì),對(duì)我們的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下

0. Spring中的五大注解

上圖中就是五大類(lèi)注解對(duì)應(yīng)的層,通過(guò)源碼可以看到其他四個(gè)注解都基于@Conponent

1. 存入 Bean

Spring既然是一個(gè)包含眾多工具方法的IoC容器,它是一個(gè)控制反轉(zhuǎn)的容器,所以就需要將Bean對(duì)象存入到容器中,需要用的時(shí)候從容器中獲取Bean對(duì)象,下面我們來(lái)介紹下存入Bean對(duì)象。

1.1 在 xml 中存入 Bean 對(duì)象

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:content="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
   // 這句代碼中, id 就是給 這個(gè)要注入的對(duì)象取個(gè)名字, class就是 要存入的 Bean 的類(lèi)型是哪一個(gè)
    <bean id = "user" class="com.java.demo.User"></bean>
</beans>

1.2 通過(guò)配置 Bean 掃描路徑 + 類(lèi)注解 實(shí)現(xiàn) Bean 的存儲(chǔ)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:content="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 通過(guò)配置掃描路徑 -->
    <content:component-scan base-package="com.java.demo"></content:component-scan>
</beans>

配置了 Bean 的掃描路徑,只有當(dāng)前目錄下的類(lèi)才會(huì)被掃描是否加了類(lèi)注解,如果加了類(lèi)注解后,就會(huì)將 所有加了類(lèi)注解的類(lèi) 存入到 IoC容器中。

@Component
public class User {
    public void say(){
        System.out.println("Hello User...");
    }
}

類(lèi)注解存Bean需要注意幾點(diǎn)

  • 如果類(lèi)名為大駝峰命名規(guī)則,那么獲取 Bean 的默認(rèn)名稱(chēng),就是 類(lèi)名首字母小寫(xiě)
  • 如果不滿(mǎn)足首字母大寫(xiě),第二個(gè)字母小寫(xiě),那么 Bean 的名稱(chēng),就是原類(lèi)名,這點(diǎn)可以看源碼知道

1.3 通過(guò)配置 Bean 掃描路徑 + 方法注解 實(shí)現(xiàn) Bean 的存儲(chǔ)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:content="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 通過(guò)配置掃描路徑 -->
    <content:component-scan base-package="com.java.demo"></content:component-scan>
</beans>
public class Student {
    private String name;
    private Integer age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
@Component
public class User {
    @Bean
    public Student student(){
        Student student = new Student();
        student.setName("張三");
        student.setAge(18);
        return student;
    }
    public void say(){
        System.out.println("Hello User...");
    }
}

在上述代碼中,我們可以通過(guò) 在方法上 加上 @Bean 注解 將該方法存入到 IoC 容器中,并且可以直接獲取到該對(duì)象。

在使用 @Bean 注解的時(shí)候,需要注意幾點(diǎn)

  • @Bean 注解必須配合 五大類(lèi)注解一塊使用
  • @Bean 注解的默認(rèn)命名 = 方法名稱(chēng)
  • 如果使用 @Bean(“xxxx”)方式,那么名稱(chēng)就是 xxxx, 并且 @Bean({“xxx”,“xxxxx”,“xxxxxx”}),里面可以類(lèi)似和數(shù)組一樣多個(gè)名稱(chēng)
  • 如果@Bean重命名后,那么默認(rèn)的方法名就沒(méi)用,獲取Bean的時(shí)候就不能寫(xiě)默認(rèn)方法名
  • 如果多個(gè) Bean 使用相同的名稱(chēng),則不會(huì)報(bào)錯(cuò),只會(huì)存儲(chǔ)第一個(gè) Bean對(duì)象,之后相同名稱(chēng)的不會(huì)存入,會(huì)自動(dòng)忽略

2. 獲取 Bean

2.1 依賴(lài)查找(DF)

依賴(lài)查找(依賴(lài)Bean的名稱(chēng)),有兩種方式,一種是 ApplicationContext, 一種是 BeanFactory。這兩種都是容器管理對(duì)象,都可以獲取到 Bean對(duì)象

2.1.1 ApplicationContext

public class App {
    public static void main(String[] args) {
        // 1. 獲取 Spring 上下文對(duì)象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2。獲取 Bean 對(duì)象
        Student student = (Student) context.getBean("student");
        System.out.println(student);
    }
}

2.1.2 BeanFactory

    public static void main(String[] args) {
        // 1. 得到 spring 上下文對(duì)象
        BeanFactory context = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
        // 2. 獲取 Bean 對(duì)象
        //Student student = (Student)context.getBean("user");
        Student student = (Student)context.getBean("student");
        System.out.println(student.toString());
    }

2.1.3 Application VS BeanFactory

ApplicationContextBeanFactory
ApplicationContext是BeanFactory的子類(lèi),其擁有更多功能(國(guó)際化支持、資源訪(fǎng)問(wèn)支持、事件傳播)BeanFactory是ApplicationContext的父類(lèi)
ApplicationContext加載Bean:一次性加載所有Bean對(duì)象BeanFactory加載Bean:懶加載,按需加載(使用一個(gè)加載一個(gè))

2.2 依賴(lài)注入(DI)

在 spring 中實(shí)現(xiàn)依賴(lài)注入的常見(jiàn)方式有3種:

  • 1.屬性注入
  • 2.setter注入
  • 3.構(gòu)造方法注入

2.2.1 屬性注入

@Controller
public class UserController {
    /**
     * 屬性注入
     */
    @Autowired
    private UserService userService;
    // 此處 main方法里面,必須使用依賴(lài)查找的方式,先獲取到UserController
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        UserController userController = (UserController) context.getBean("userController");
        userController.userService.say();
    }
}

屬性注入:

優(yōu)點(diǎn): 實(shí)現(xiàn)簡(jiǎn)單、使用簡(jiǎn)單,只需要在屬性上加一個(gè)注解@Autowired,就不需要自己new一個(gè)對(duì)象,直接獲得注入的對(duì)象。

缺點(diǎn):

  • 無(wú)法注入一個(gè)用 final 修飾的對(duì)象

  •  因?yàn)樵贘ava語(yǔ)法中,final修飾的對(duì)象(不可變),要么一開(kāi)始就賦值,要么在構(gòu)造方法里面賦值。而上述使用屬性注入,注入final修飾的對(duì)象,就不符合規(guī)范,所以不行。
  • 只能適用于 IoC 容器:如果將這些代碼放到其他非IoC容器中,那么代碼就會(huì)失效
  • 設(shè)計(jì)原則:更容易違背單一原則,因?yàn)閷傩宰⑷氡容^簡(jiǎn)單,那么可能就會(huì)在一個(gè)類(lèi)中注入多個(gè)對(duì)象,這就可能不符合程序的單一職責(zé)問(wèn)題。

2.2.2 Setter注入

@Controller
public class UserController2 {
    private UserService userService;
    /**
     * setter注入
     */
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        UserController2 userController2 = (UserController2) context.getBean("userController2");
        userController2.userService.say();
    }
}

優(yōu)點(diǎn):似乎沒(méi)什么優(yōu)點(diǎn),而且比屬性注入更加麻煩,要說(shuō)唯一可能有用的就是,完全符合單一職責(zé)設(shè)計(jì)原則,每個(gè) setter 只針對(duì)一個(gè)對(duì)象。Setter注入 也適用于非IoC容器
缺點(diǎn):

  • 不能注入 final 對(duì)象

  • 由于是 Setter 注入,提供了 set 方法,那么注入的對(duì)象可以隨時(shí)被更改

2.2.3 構(gòu)造方法注入(Spring4.x之后推薦的)

@Controller
public class UserController3 {
    private final UserService userService;
    /**
     * 構(gòu)造方法注入
     */
    // @Autowired 此處如果構(gòu)造方法參數(shù)只有一個(gè)的時(shí)候,該注解可有可無(wú)
    public UserController3(UserService userService) {
        this.userService = userService;
    }
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        UserController3 userController3 = (UserController3) context.getBean("userController3");
        userController3.userService.say();
    }
}

優(yōu)點(diǎn):

  • 可以注入 被final 修飾的對(duì)象

  • 注入對(duì)象不會(huì)被更改,因?yàn)槭窃跇?gòu)造方法注入的,構(gòu)造方法在對(duì)象創(chuàng)建的時(shí)候只會(huì)創(chuàng)建一次

  • 注入的對(duì)象會(huì)被完全初始化

  • 通用性會(huì)更好,無(wú)論在 IoC容器 還是 非 IoC容器中都能用

缺點(diǎn):

  • 寫(xiě)法更加復(fù)雜
  • 使用構(gòu)造方法,無(wú)法解決循環(huán)依賴(lài)的問(wèn)題

Spring官方推薦的是構(gòu)造方法的注入,可以注入不可變對(duì)象,通用性更好;如果想要注入可變對(duì)象,那么可以使用 Setter 注入。

3. 解決同一類(lèi)型多個(gè) Bean 的報(bào)錯(cuò)問(wèn)題

上述代碼,可以看到報(bào)錯(cuò),出現(xiàn)了多個(gè)同一類(lèi)型的多個(gè)Bean報(bào)錯(cuò),需要1個(gè),找到了2個(gè)。如何解決呢

  • 1.@Autowired 配合 @Qualifier(value = “xxx”)一起使用,里面參數(shù)加方法名字

  • 2.使用@Resource(name = “xxxx”)

4. @Resource 和 @Autowired

  • 出身不同:@Resource來(lái)自于JDK,@Resource來(lái)自于Spring

  • 支持參數(shù)不同:@Resource支持更多的參數(shù)

  • @Autowired只支持一個(gè)參數(shù)設(shè)置

  • 使用上的區(qū)別:@Resource不支持構(gòu)造方法的注入

  • 兼容性問(wèn)題:@Autowired在社區(qū)版 IDEA可能會(huì)誤報(bào);

以上就是一文帶你了解Spring中存入Bean和獲取Bean的方式的詳細(xì)內(nèi)容,更多關(guān)于Spring存入和獲取Bean方式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Mybatis @SelectKey用法解讀

    Mybatis @SelectKey用法解讀

    這篇文章主要介紹了Mybatis @SelectKey用法解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java異常鏈表throw結(jié)構(gòu)assert詳細(xì)解讀

    Java異常鏈表throw結(jié)構(gòu)assert詳細(xì)解讀

    這篇文章主要給大家介紹了關(guān)于Java中方法使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • SpringBoot項(xiàng)目打包發(fā)布到外部tomcat(出現(xiàn)各種異常的解決)

    SpringBoot項(xiàng)目打包發(fā)布到外部tomcat(出現(xiàn)各種異常的解決)

    這篇文章主要介紹了SpringBoot項(xiàng)目打包發(fā)布到外部tomcat(出現(xiàn)各種異常的解決),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 一文帶你了解Spring的Bean初始化過(guò)程和生命周期

    一文帶你了解Spring的Bean初始化過(guò)程和生命周期

    Spring的核心功能有三點(diǎn)IOC、DI、AOP,IOC則是基礎(chǔ),也是Spring功能的最核心的點(diǎn)之一。今天一起來(lái)總結(jié)下Spring中Bean是怎么被創(chuàng)建出來(lái)的
    2023-03-03
  • Java實(shí)現(xiàn)身份證號(hào)碼驗(yàn)證源碼示例分享

    Java實(shí)現(xiàn)身份證號(hào)碼驗(yàn)證源碼示例分享

    本篇文章主要介紹了Java實(shí)現(xiàn)身份證號(hào)碼驗(yàn)證源碼示例分享,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • Idea中maven無(wú)法下載依賴(lài)包問(wèn)題解決

    Idea中maven無(wú)法下載依賴(lài)包問(wèn)題解決

    用過(guò)idea開(kāi)發(fā)過(guò)項(xiàng)目的同學(xué),偶爾會(huì)遇到項(xiàng)目中有一些依賴(lài)沒(méi)法下載,或者依賴(lài)包已經(jīng)有項(xiàng)目卻無(wú)法掃到的問(wèn)題,本文就詳細(xì)的介紹了解決方法,感興趣的可以了解一下
    2020-08-08
  • Spring boot actuator端點(diǎn)啟用和暴露操作

    Spring boot actuator端點(diǎn)啟用和暴露操作

    這篇文章主要介紹了Spring boot actuator端點(diǎn)啟用和暴露操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 詳解SpringBoot同時(shí)可以處理多少請(qǐng)求

    詳解SpringBoot同時(shí)可以處理多少請(qǐng)求

    在日常操作中,相信很多人在SpringBoot能同時(shí)處理多少請(qǐng)求問(wèn)題上存在疑惑,本文就來(lái)詳細(xì)的介紹一下,感興趣的可以了解一下
    2024-06-06
  • Java實(shí)現(xiàn)的校驗(yàn)銀行卡功能示例

    Java實(shí)現(xiàn)的校驗(yàn)銀行卡功能示例

    這篇文章主要介紹了Java實(shí)現(xiàn)的校驗(yàn)銀行卡功能,結(jié)合完整實(shí)例形式分析了java針對(duì)銀行卡類(lèi)型、歸屬地等信息的判斷、讀取相關(guān)操作技巧,需要的朋友可以參考下
    2018-06-06
  • Java設(shè)計(jì)模式之訪(fǎng)問(wèn)者模式

    Java設(shè)計(jì)模式之訪(fǎng)問(wèn)者模式

    這篇文章介紹了Java設(shè)計(jì)模式之訪(fǎng)問(wèn)者模式,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10

最新評(píng)論