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

解讀Spring定義Bean的兩種方式:<bean>和@Bean

 更新時(shí)間:2023年04月04日 10:04:46   作者:恐龍弟旺仔  
這篇文章主要介紹了Spring定義Bean的兩種方式:<bean>和@Bean,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

前言    

Spring中最重要的概念I(lǐng)OC和AOP,實(shí)際圍繞的就是Bean的生成與使用。

什么叫做Bean呢?我們可以理解成對(duì)象,每一個(gè)你想交給Spring去托管的對(duì)象都可以稱(chēng)之為Bean。

今天通過(guò)Spring官方文檔來(lái)了解下,如何生成bean,如何使用呢?

1.通過(guò)XML的方式來(lái)生成一個(gè)bean

最簡(jiǎn)單也是最原始的一種方式,通過(guò)XML來(lái)定義一個(gè)bean,我們來(lái)看下其過(guò)程

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)造:使用成員變量名稱(chēng)對(duì)應(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對(duì)應(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)造:使用成員變量類(lèi)型對(duì)應(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的方式多種多樣,我們可以通過(guò)屬性來(lái)賦值<property>,也可以通過(guò)構(gòu)造參數(shù)來(lái)賦值<constructor>,關(guān)于構(gòu)造賦值以上展示了三種方式,我們可以根據(jù)自己的需求來(lái)選擇對(duì)應(yīng)的方式。

3)測(cè)試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使用方式,大家會(huì)發(fā)現(xiàn)<bean>標(biāo)簽還有其他的屬性,比如name/scope/lazy-init/init-method/...等,這些是做什么用的呢?我們?cè)趯?shí)際的工作中怎么使用呢?

1)name屬性

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

* ApplicationContext.getBean(String name)

* ApplicationContext.getBean(Class<T> requiredType)

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

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

Student studentNoValue = (Student) applicationContext.getBean(Student.class);

2)scope屬性

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

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

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

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

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

* 下面來(lái)驗(yàn)證下原型模式

原型模式:每次獲取的bean都為一個(gè)新的對(duì)象

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

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

3)init-method和destroy-method方法

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

// 在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"/>
?
// 測(cè)試方法如下:
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
Student studentNoValue = (Student) applicationContext.getBean("stuName");
?
applicationContext.close();
?
// 執(zhí)行結(jié)果:
student init...
student destroy... ? ?

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

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

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

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

3.JavaConfig方式的bean定義

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

1)如何定義一個(gè)Bean

// 創(chuàng)建一個(gè)類(lèi),命名為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)

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

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

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

* 通過(guò)AnnotationConfigApplicationContext來(lái)加載JavaConfig

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

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

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

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

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

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

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

總結(jié)

以上全文,我們通過(guò)兩種方式來(lái)定義一個(gè)Bean,默認(rèn)推薦JavaConfig。

還有一些其他屬性,筆者就不一一列舉了。

這些僅為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

參考:

Spring Framework Reference Documentation

代碼地址:GitHub - kldwz/springstudy   

相關(guān)文章

  • Java 8 lambda表達(dá)式引入詳解及實(shí)例

    Java 8 lambda表達(dá)式引入詳解及實(shí)例

    這篇文章主要介紹了Java 8 lambda表達(dá)式引入詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Java?restTemplate發(fā)送get請(qǐng)求query參數(shù)傳遞問(wèn)題解決

    Java?restTemplate發(fā)送get請(qǐng)求query參數(shù)傳遞問(wèn)題解決

    這篇文章主要為大家介紹了Java?restTemplate發(fā)送get請(qǐng)求query參數(shù)傳遞問(wèn)題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Java之進(jìn)程和線程的區(qū)別

    Java之進(jìn)程和線程的區(qū)別

    這篇文章主要介紹了進(jìn)程與線程的區(qū)別,線程具有許多傳統(tǒng)進(jìn)程所具有的特征,而把傳統(tǒng)的進(jìn)程稱(chēng)為重型進(jìn)程(Heavy—Weight Process),它相當(dāng)于只有一個(gè)線程的任務(wù),有感興趣的小伙伴可以參考閱讀本文
    2023-03-03
  • java實(shí)現(xiàn)日歷效果的示例代碼

    java實(shí)現(xiàn)日歷效果的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何使用java實(shí)現(xiàn)打印某年全部的日歷信息,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以學(xué)習(xí)一下
    2023-12-12
  • java從文件中讀取數(shù)據(jù)的六種方法

    java從文件中讀取數(shù)據(jù)的六種方法

    本文主要介紹了java從文件中讀取數(shù)據(jù)的方法,詳細(xì)的介紹了六種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Java中重載與重寫(xiě)的對(duì)比與區(qū)別

    Java中重載與重寫(xiě)的對(duì)比與區(qū)別

    這篇文章主要介紹了Java中重載與重寫(xiě)的對(duì)比與區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Java利用反射獲取object的屬性和值代碼示例

    Java利用反射獲取object的屬性和值代碼示例

    這篇文章主要介紹了Java利用反射獲取object的屬性和值代碼示例,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Java代理深入講解之靜態(tài)代理

    Java代理深入講解之靜態(tài)代理

    這篇文章主要給大家介紹了關(guān)于Java靜態(tài)代理的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • JAVA IO API使用詳解

    JAVA IO API使用詳解

    本文通過(guò)理論、用法、實(shí)例詳細(xì)說(shuō)明了JAVA IO的使用,大家參考其中的實(shí)例代碼實(shí)現(xiàn)自己的JAVA IO程序
    2013-11-11
  • ServletContext中常用方法介紹

    ServletContext中常用方法介紹

    本篇文章是對(duì)ServletContext中的常用方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-07-07

最新評(píng)論

大渡口区| 哈尔滨市| 伽师县| 陇川县| 海伦市| 定安县| 包头市| 虹口区| 卢湾区| 龙泉市| 漳浦县| 顺平县| 墨玉县| 门源| 棋牌| 嘉祥县| 仪陇县| 财经| 辽阳县| 巴南区| 淮滨县| 昌乐县| 香河县| 海伦市| 鄂州市| 密山市| 深圳市| 鄂托克前旗| 高要市| 阳高县| 博野县| 双鸭山市| 内乡县| 诸暨市| 磐安县| 如皋市| 伊金霍洛旗| 锡林郭勒盟| 嵊州市| 大城县| 芦山县|