溫馨提示×

溫馨提示×

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

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

Spring定義Bean的方式有哪些

發(fā)布時間:2023-05-09 15:11:04 來源:億速云 閱讀:108 作者:zzz 欄目:開發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“Spring定義Bean的方式有哪些”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Spring定義Bean的方式有哪些”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。

    1.通過XML的方式來生成一個bean

    最簡單也是最原始的一種方式,通過XML來定義一個bean,我們來看下其過程

    1)創(chuàng)建entity,命名為Student

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Student implements Serializable {
     
        private static final long serialVersionUID = -2088281526481179972L;
        private int id;
        private String name;
        private int age;
    }

    2)在beans.xml中定義Student

        <!-- 1.空值的student -->
        <bean id="studentNoValue" class="domain.Student"/>
     
        <!-- 2.帶值的student -->
        <bean id="student" class="domain.Student">
            <property name="id" value="11"/>
            <property name="age" value="22"/>
            <property name="name" value="jack"/>
        </bean>
     
        <!-- 3.全參構(gòu)造:使用成員變量名稱對應(yīng) -->
        <bean id="studentConstruct" class="domain.Student">
            <constructor-arg name="age" value="22"></constructor-arg>
            <constructor-arg name="id" value="11"></constructor-arg>
            <constructor-arg name="name" value="jack"></constructor-arg>
        </bean>
     
        <!-- 4.全參構(gòu)造:使用成員變量index對應(yīng) -->
        <bean id="studentConstruct2" class="domain.Student">
            <constructor-arg index="0" value="11"></constructor-arg>
            <constructor-arg index="1" value="jack"></constructor-arg>
            <constructor-arg index="2" value="22"></constructor-arg>
        </bean>
     
        <!-- 5.全參構(gòu)造:使用成員變量類型對應(yīng) -->
        <bean id="studentConstruct3" class="domain.Student">
            <constructor-arg type="int" value="11"></constructor-arg>
            <constructor-arg type="java.lang.String" value="jack"></constructor-arg>
            <constructor-arg type="int" value="22"></constructor-arg>
        </bean>

    總結(jié):可以看到,創(chuàng)建bean的方式多種多樣,我們可以通過屬性來賦值<property>,也可以通過構(gòu)造參數(shù)來賦值<constructor>,關(guān)于構(gòu)造賦值以上展示了三種方式,我們可以根據(jù)自己的需求來選擇對應(yīng)的方式。

    3)測試bean

    public class ApplicationContextTest {
     
        @Test
        public void testXml(){
            ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
            Student studentNoValue = (Student) applicationContext.getBean("studentNoValue");
            Student studentFullValue = (Student) applicationContext.getBean("studentFullValue");
            System.out.println(studentNoValue);
            System.out.println(studentFullValue);
     
     
            Student studentConstruct1 = (Student) applicationContext.getBean("studentConstruct");
            Student studentConstruct2 = (Student) applicationContext.getBean("studentConstruct2");
            Student studentConstruct3 = (Student) applicationContext.getBean("studentConstruct3");
            System.out.println(studentConstruct1);
            System.out.println(studentConstruct2);
            System.out.println(studentConstruct3);
     
            Book bookChinese = (Book) applicationContext.getBean("bookChinese");
            System.out.println(bookChinese);
        }
    }
    // res:
    Student(id=0, name=null, age=0)
    Student(id=11, name=jack, age=22)
    Student(id=11, name=jack, age=22)
    Student(id=11, name=jack, age=22)
    Student(id=11, name=jack, age=22)

    2.<bean>標(biāo)簽深入了解

    我們剛才介紹了最基本的Bean使用方式,大家會發(fā)現(xiàn)<bean>標(biāo)簽還有其他的屬性,比如name/scope/lazy-init/init-method/...等,這些是做什么用的呢?我們在實際的工作中怎么使用呢?

    1)name屬性

    在介紹name屬性之前,我們先來看下ApplicationContext.getBean()的兩種方式

    * ApplicationContext.getBean(String name)

    * ApplicationContext.getBean(Class<T> requiredType)

    第一種方式的這個name是什么呢?我們應(yīng)該如何定義,又該如何使用呢?

    // 上文示例中,我們只是指定了Bean的id和class,如下所示
    <bean id="studentNoValue" class="domain.Student" />
        
    // 具體獲取bean的方式如下:
    Student studentNoValue = (Student) applicationContext.getBean("studentNoValue");
     
    // 可以看到,在沒有指定bean的name屬性的時候,默認(rèn)使用id來獲取bean,當(dāng)做name使用
    // 如果我們不想根據(jù)id獲取,那就需要主動指定bean的name屬性,如下所示:
    <bean id="studentNoValue" class="domain.Student" name="stuName"/>
    // 這樣在獲取的時候,就需要使用指定的名稱來獲取,再根據(jù)id來獲取的時候就會報錯了
    Student studentNoValue = (Student) applicationContext.getBean("stuName");
        * 根據(jù)Class來獲取這種方式很好理解,這個不關(guān)心你定義的id或者name是什么,使用如下:
    
    Student studentNoValue = (Student) applicationContext.getBean(Student.class);

    2)scope屬性

    可以看到,在使用scope屬性的時候,提示有兩種輸入值,分別是singleton/prototype

    這個就代表了Spring-Bean的兩種創(chuàng)建模式,單例模式和原型模式

    * Spring默認(rèn)使用單例模式來創(chuàng)建Bean,通過ApplicationContext所獲得的bean都是同一個bean(在beanName相同的情況下),我們可以來驗證下

    Student studentNoValue = (Student) applicationContext.getBean("stuName");
    Student studentNoValue2 = (Student) applicationContext.getBean("stuName");
     
    System.out.println(studentNoValue == studentNoValue2);// true

    可以看到的是結(jié)果輸入為true,從工廠類中兩次獲取的stuName是同一個對象。

    * 下面來驗證下原型模式

    原型模式:每次獲取的bean都為一個新的對象

    // 修改beans.xml中studentNoValue的scope為prototype
    <bean id="studentNoValue" class="domain.Student" name="stuName" scope="prototype"/>
     
    // 然后執(zhí)行上面的測試代碼
    Student studentNoValue = (Student) applicationContext.getBean("stuName");
    Student studentNoValue2 = (Student) applicationContext.getBean("stuName");
     
    System.out.println(studentNoValue == studentNoValue2);// false

    可以看到,輸出結(jié)果為false,原型模式下從工廠類兩次獲取的stuName不是同一個對象。

    3)init-method和destroy-method方法

    見名知意,init-method應(yīng)該是初始化方法的意思,destroy-method應(yīng)該是銷毀方法的意思。那怎么使用呢?

    // 在Student.java中添加init()方法和destroy()方法
    public void init(){
        System.out.println("student init...");
    }
     
    public void destroy(){
        System.out.println("student destroy...");
    }
     
    // 在beans.xml中studentNoValue的bean上添加 init-method和destroy-method
    <bean id="studentNoValue" class="domain.Student" name="stuName" init-method="init" destroy-method="destroy"/>
     
    // 測試方法如下:
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
    Student studentNoValue = (Student) applicationContext.getBean("stuName");
     
    applicationContext.close();
     
    // 執(zhí)行結(jié)果:
    student init...
    student destroy...

    總結(jié):在獲取bean的時候init()方法被執(zhí)行,在容器被銷毀的時候,執(zhí)行了destroy()方法

    根據(jù)這個,我們可以在初始化bean和銷毀bean的時候做點什么,比如關(guān)閉連接,保存記錄之類的操作。

    延伸:那么初始化init()方法在構(gòu)造方法之前調(diào)用,還是之后調(diào)用呢?讀者可以自行驗證下

    總結(jié):還有一些其他屬性,筆者就不再一一驗證了,下面說一下通過JavaConfig的方法來實現(xiàn)bean的定義。

    3.JavaConfig方式的bean定義

    JavaConfig是Spring4.x推薦的配置方式,可以完全替代XML的方式定義。

    1)如何定義一個Bean

    // 創(chuàng)建一個類,命名為SpringConfiguration
    @Configuration
    public class SpringConfiguration {
        @Bean
        public Student student(){
            return new Student(11,"jack",22);
        }
    }
     
    // 使用bean
    AnnotationConfigApplicationContext applicationContext
                    = new AnnotationConfigApplicationContext(SpringConfiguration.class);
    Student student = (Student) applicationContext.getBean("student")
    System.out.println(student);
     
    // res:
    Student(id=11, name=jack, age=22)

    相對于XML的使用方式而言,JavaConfig的使用方式基本是同步的

    * @Configuration等同于<beans></beans>

    * @Bean等同于<bean></bean>

    * 通過AnnotationConfigApplicationContext來加載JavaConfig

    * 方法名student()就等同于<bean>中的id,默認(rèn)方法名就是beanName

    2)@Bean的其他參數(shù)

    * name屬性等同于<bean>的name

    * initMethod屬性等同于<bean>的init-method

    * destroyMethod屬性等同于<bean>的destroy-method

    * scope這個比較奇怪,不屬于@Bean的參數(shù),這是一個單獨的注解,使用方式如下

    @Bean(name = "stu",autowire = Autowire.BY_TYPE)
    @Scope(value = "singleton")
    public Student student(){
        return new Student(11,"jack",22);
    }

    讀到這里,這篇“Spring定義Bean的方式有哪些”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI