spring bean定義和自動注入

一、定義bean的三種途徑:

  • 首先編寫Student和Teacher兩個類
test/Student.java
[java] view plain copy
  1. public class Student {  
  2.   
  3.     private String name;  
  4.   
  5.     private Teacher teacher;  
  6.   
  7.     public String getName() {  
  8.         return name;  
  9.     }  
  10.   
  11.     public void setName(String name) {  
  12.         this.name = name;  
  13.     }  
  14.   
  15.     public Teacher getTeacher() {  
  16.         return teacher;  
  17.     }  
  18.   
  19.     public void setTeacher(Teacher teacher) {  
  20.         this.teacher = teacher;  
  21.     }  
  22.   
  23. }  
test/Teacher.java
[java] view plain copy
  1. public class Teacher {  
  2.   
  3.     private String name;  
  4.   
  5.     public String getName() {  
  6.         return name;  
  7.     }  
  8.   
  9.     public void setName(String name) {  
  10.         this.name = name;  
  11.     }  
  12.   
  13. }  

  • 方法一:基於XML的bean定義(需要提供setter方法)
[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">  
  5.   
  6.     <bean id="student" class="test.Student">  
  7.         <property name="name" value="張三"/>  
  8.         <property name="teacher" ref="teacher"/>  
  9.     </bean>  
  10.   
  11.     <bean id="teacher" class="test.Teacher">  
  12.         <property name="name" value="李四"/>  
  13.     </bean>  
  14.   
  15. </beans>  
[java] view plain copy
  1. public class Main {  
  2.   
  3.     public static void main(String args[]){  
  4.         FileSystemXmlApplicationContext context=new FileSystemXmlApplicationContext("applicationContext.xml的絕對路徑");  
  5.         Student student= (Student) context.getBean("student");  
  6.         Teacher teacher= (Teacher) context.getBean("teacher");  
  7.         System.out.println("學生的姓名:"+student.getName()+"。老師是"+student.getTeacher().getName());  
  8.         System.out.println("老師的姓名:"+teacher.getName());  
  9.     }  
  10.   
  11. }  

  • 方法二:基於註解的bean定義(不需要提供setter方法)
Spring爲此提供了四個註解,這些註解的作用與上面的XML定義bean效果一致,在於將組件交給Spring容器管理。組件的名稱默認是類名(首字母變小寫),也可以自己修改:
@Component:當對組件的層次難以定位的時候使用這個註解
@Controller:表示控制層的組件
@Service:表示業務邏輯層的組件
@Repository:表示數據訪問層的組件
使用這些註解的時候還有一個地方需要注意,就是需要在applicationContext.xml中聲明<contex:component-scan...>一項,指明Spring容器掃描組件的包目錄。
[java] view plain copy
  1. @Component("teacher")  
  2. public class Teacher {  
  3.   
  4.     @Value("李四")  
  5.     private String name;  
  6.   
  7.     public String getName() {  
  8.         return name;  
  9.     }  
  10.   
  11. }  
[java] view plain copy
  1. @Component("student")  
  2. public class Student {  
  3.   
  4.     @Value("張三")  
  5.     private String name;  
  6.   
  7.     @Resource  
  8.     private Teacher teacher;  
  9.   
  10.     public String getName() {  
  11.         return name;  
  12.     }  
  13.   
  14.     public Teacher getTeacher() {  
  15.         return teacher;  
  16.     }  
  17.   
  18. }  
[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xmlns:context="http://www.springframework.org/schema/context"  
  5.        xsi:schemaLocation="http://www.springframework.org/schema/beans  
  6.        http://www.springframework.org/schema/beans/spring-beans.xsd  
  7.        http://www.springframework.org/schema/context  
  8.        http://www.springframework.org/schema/context/spring-context.xsd">  
  9.   
  10.     <!--掃描組件的包目錄-->  
  11.     <context:component-scan base-package="test"/>  
  12.   
  13. </beans>  
[java] view plain copy
  1. public class Main {  
  2.   
  3.     public static void main(String args[]){  
  4.         FileSystemXmlApplicationContext context=new FileSystemXmlApplicationContext("applicationContext.xml的絕對路徑");  
  5.         Student student= (Student) context.getBean("student");  
  6.         Teacher teacher= (Teacher) context.getBean("teacher");  
  7.         System.out.println("學生的姓名:"+student.getName()+"。老師是"+student.getTeacher().getName());  
  8.         System.out.println("老師的姓名:"+teacher.getName());  
  9.     }  
  10.   
  11. }  

  • 方法三:基於Java類的bean定義(需要提供setter方法)
[java] view plain copy
  1. @Configuration  
  2. public class BeansConfiguration {  
  3.   
  4.     @Bean  
  5.     public Student student(){  
  6.         Student student=new Student();  
  7.         student.setName("張三");  
  8.         student.setTeacher(teacher());  
  9.         return student;  
  10.     }  
  11.   
  12.     @Bean  
  13.     public Teacher teacher(){  
  14.         Teacher teacher=new Teacher();  
  15.         teacher.setName("李四");  
  16.         return teacher;  
  17.     }  
  18.   
  19. }  
[java] view plain copy
  1. public class Main {  
  2.   
  3.     public static void main(String args[]){  
  4.         AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(BeansConfiguration.class);  
  5.         Student student= (Student) context.getBean("student");  
  6.         Teacher teacher= (Teacher) context.getBean("teacher");  
  7.         System.out.println("學生的姓名:"+student.getName()+"。老師是"+student.getTeacher().getName());  
  8.         System.out.println("老師的姓名:"+teacher.getName());  
  9.     }  
  10.   
  11. }  


二、Spring的自動注入

  • Spring提供了五種自動裝配的類型
no:顧名思義, 顯式指明不使用Spring的自動裝配功能
byName:根據屬性和組件的名稱匹配關係來實現bean的自動裝配
byType:根據屬性和組件的類型匹配關係來實現bean的自動裝配,有多個適合類型的對象時裝配失敗
constructor:與byType類似是根據類型進行自動裝配,但是要求待裝配的bean有相應的構造函數
autodetect:利用Spring的自省機制判斷使用byType或是constructor裝配


  • 基於XML的自動裝配
[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.        http://www.springframework.org/schema/beans/spring-beans.xsd">  
  6.   
  7.     <bean id="student" class="test.Student" autowire="byName">  
  8.         <property name="name" value="張三"/>  
  9.     </bean>  
  10.   
  11.     <bean id="teacher" class="test.Teacher">  
  12.         <property name="name" value="李四"/>  
  13.     </bean>  
  14.   
  15. </beans>  
這裏我並沒有顯式爲Student對象注入Teacher屬性,而是使用autowired="byName"代替,這樣一來Spring會幫我們處理這些細節,將名字是teacher的組件注入到Student對象中。

  • 基於註解的自動裝配
其實上面已經應用過了,這裏再提一下@Resource和@Autowired的區別。@Resource默認是使用byName進行裝配,@Autowired默認使用byType進行裝配。
[java] view plain copy
  1. @Component("teacher")  
  2. public class Teacher {  
  3.   
  4.     @Value("李四")  
  5.     private String name;  
  6.   
  7.     public String getName() {  
  8.         return name;  
  9.     }  
  10.   
  11.     public void setName(String name) {  
  12.         this.name = name;  
  13.     }  
  14. }  
[java] view plain copy
  1. @Component("student")  
  2. public class Student {  
  3.   
  4.     @Value("張三")  
  5.     private String name;  
  6.   
  7.     @Resource  
  8.     private Teacher teacher;  
  9.   
  10.     public String getName() {  
  11.         return name;  
  12.     }  
  13.   
  14.     public void setName(String name) {  
  15.         this.name = name;  
  16.     }  
  17.   
  18.     public Teacher getTeacher() {  
  19.         return teacher;  
  20.     }  
  21.   
  22.     public void setTeacher(Teacher teacher) {  
  23.         this.teacher = teacher;  
  24.     }  
  25. }  


三、如何進行選擇?

其實說了這麼多,我們應該如何對這些不同方式進行權衡和選擇呢?這個見仁見智,我說說我常用的方式。
  • 定義bean:一般我使用基於註解的bean定義。這樣可以擺脫使用XML或是Java類對大量bean進行配置的噩夢,讓程序變得簡潔。註解還可以清楚地指明組件所在的層次。但是也有特殊的情況,比如說配置數據源,也許某個組件並不是你寫的(來自於Spring或是第三方jar包裏面的組件等),你沒有辦法在這些組件裏面加上這些註解使之成爲Spring容器管理的bean(別人也不會爲你加上這些註解,因爲他們不知道你會使用到哪些組件)。這種情況下就得使用XML或是Java類進行配置了,個人比較喜歡XML配置。如下例子:
[html] view plain copy
  1. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
  2.         <property name="driverClassName" value="com.mysql.jdbc.Driver"/>  
  3.         <property name="url" value="jdbc:mysql://localhost:3306/study"/>  
  4.         <property name="username" value="賬號"/>  
  5.         <property name="password" value="密碼"/>  
  6.     </bean>  

  • 自動裝配:一般我使用基於註解的自動裝配。同樣也是爲了減少XML配置文件的“篇幅”。
  • 通過使用基於註解的bean定義和自動裝配,大大減少了XML配置文件的長度,增加了程序的可讀性。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章