您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“Spring定義Bean的方式有哪些”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Spring定義Bean的方式有哪些”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
最簡單也是最原始的一種方式,通過XML來定義一個bean,我們來看下其過程
@Data @AllArgsConstructor @NoArgsConstructor public class Student implements Serializable { private static final long serialVersionUID = -2088281526481179972L; private int id; private String name; private int age; }
<!-- 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.全參構造:使用成員變量名稱對應 --> <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.全參構造:使用成員變量index對應 --> <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.全參構造:使用成員變量類型對應 --> <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>
總結:可以看到,創建bean的方式多種多樣,我們可以通過屬性來賦值<property>,也可以通過構造參數來賦值<constructor>,關于構造賦值以上展示了三種方式,我們可以根據自己的需求來選擇對應的方式。
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)
我們剛才介紹了最基本的Bean使用方式,大家會發現<bean>標簽還有其他的屬性,比如name/scope/lazy-init/init-method/...等,這些是做什么用的呢?我們在實際的工作中怎么使用呢?
在介紹name屬性之前,我們先來看下ApplicationContext.getBean()的兩種方式
* ApplicationContext.getBean(String name)
* ApplicationContext.getBean(Class<T> requiredType)
第一種方式的這個name是什么呢?我們應該如何定義,又該如何使用呢?
// 上文示例中,我們只是指定了Bean的id和class,如下所示 <bean id="studentNoValue" class="domain.Student" /> // 具體獲取bean的方式如下: Student studentNoValue = (Student) applicationContext.getBean("studentNoValue"); // 可以看到,在沒有指定bean的name屬性的時候,默認使用id來獲取bean,當做name使用 // 如果我們不想根據id獲取,那就需要主動指定bean的name屬性,如下所示: <bean id="studentNoValue" class="domain.Student" name="stuName"/> // 這樣在獲取的時候,就需要使用指定的名稱來獲取,再根據id來獲取的時候就會報錯了 Student studentNoValue = (Student) applicationContext.getBean("stuName"); * 根據Class來獲取這種方式很好理解,這個不關心你定義的id或者name是什么,使用如下: Student studentNoValue = (Student) applicationContext.getBean(Student.class);
可以看到,在使用scope屬性的時候,提示有兩種輸入值,分別是singleton/prototype
這個就代表了Spring-Bean的兩種創建模式,單例模式和原型模式
* Spring默認使用單例模式來創建Bean,通過ApplicationContext所獲得的bean都是同一個bean(在beanName相同的情況下),我們可以來驗證下
Student studentNoValue = (Student) applicationContext.getBean("stuName"); Student studentNoValue2 = (Student) applicationContext.getBean("stuName"); System.out.println(studentNoValue == studentNoValue2);// true
可以看到的是結果輸入為true,從工廠類中兩次獲取的stuName是同一個對象。
* 下面來驗證下原型模式
原型模式:每次獲取的bean都為一個新的對象
// 修改beans.xml中studentNoValue的scope為prototype <bean id="studentNoValue" class="domain.Student" name="stuName" scope="prototype"/> // 然后執行上面的測試代碼 Student studentNoValue = (Student) applicationContext.getBean("stuName"); Student studentNoValue2 = (Student) applicationContext.getBean("stuName"); System.out.println(studentNoValue == studentNoValue2);// false
可以看到,輸出結果為false,原型模式下從工廠類兩次獲取的stuName不是同一個對象。
見名知意,init-method應該是初始化方法的意思,destroy-method應該是銷毀方法的意思。那怎么使用呢?
// 在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(); // 執行結果: student init... student destroy...
總結:在獲取bean的時候init()方法被執行,在容器被銷毀的時候,執行了destroy()方法
根據這個,我們可以在初始化bean和銷毀bean的時候做點什么,比如關閉連接,保存記錄之類的操作。
延伸:那么初始化init()方法在構造方法之前調用,還是之后調用呢?讀者可以自行驗證下
總結:還有一些其他屬性,筆者就不再一一驗證了,下面說一下通過JavaConfig的方法來實現bean的定義。
JavaConfig是Spring4.x推薦的配置方式,可以完全替代XML的方式定義。
// 創建一個類,命名為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,默認方法名就是beanName
* name屬性等同于<bean>的name
* initMethod屬性等同于<bean>的init-method
* destroyMethod屬性等同于<bean>的destroy-method
* scope這個比較奇怪,不屬于@Bean的參數,這是一個單獨的注解,使用方式如下
@Bean(name = "stu",autowire = Autowire.BY_TYPE) @Scope(value = "singleton") public Student student(){ return new Student(11,"jack",22); }
讀到這里,這篇“Spring定義Bean的方式有哪些”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。