Spring基础知识(4)- Spring Bean (一)


在 Spring 中,构成应用程序主干并由 Spring IoC 容器管理的对象称为 Bean。Bean 是一个由 Spring IoC 容器实例化、装配和管理的对象。

简而言之:
    (1) Bean 是对象,一个或者多个不限定;
    (2) Bean 由 Spring IoC 容器管理;
    (3) Bean 是 Spring 应用程序的主要组成部分(或称为主要的功能模块);

IoC 容器通过获取 Java 类和该类相关的 Spring 配置元数据来进行实例化、装配和管理 Bean。

Spring 配置元数据一般包含如下信息:

    (1) 如何创建一个 Bean;
    (2) Bean 的作用域、生命周期等信息;
    (3) Bean 的依赖关系、如何装配等信息;

Spring 的三种 Bean 配置方式:

    (1) 基于配置文件 (XML格式、Properties格式) 的配置方式;
    (2) 基于注解的配置方式;
    (3) 基于Java配置(@Configuration)的配置方式;

    即 Spring 配置元数据,可以在配置文件里,或在注解中。本文只讨论前两种,Java配置(@Configuration)后面单独讨论。


1. 基于配置文件 (XML格式和Properties格式) 的配置方式

    (1) Beans 配置文件 (主配置文件)

 1         <?xml version="1.0" encoding="UTF-8"?>
 2          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-4.0.xsd
 7                                 http://www.springframework.org/schema/context
 8                                 http://www.springframework.org/schema/context/spring-context-4.0.xsd" >
 9             
10             class="com.example.Man">
11                 
12                 
13 
14                 
15                 
16                 
17 
18             
19             class="com.example.Person">
20                 
21                 
22 
23                 
24                 
25                 
26                 
27                 <null/>
28                  
29 
30                 
31                 
32                     ]]>
33                 
34 
35                 
36                 
37                     
38                         Array 1
39                         Array 2
40                         Array 3
41                     
42                 
43                 
44                     
45                         List 1
46                         List 2
47                         List 3
48                     
49                 
50                 
51                     
52                         
53                         
54                     
55                 
56                 
57                     
58                         Set 1
59                         Set 2
60                         Set 3
61                     
62                 
63 
64             
65 
66         

        上面的 标签就是用于配置 Bean 对象让 Spring 来创建的,标签就是告诉  Spring 使用构造函数注入,标签就是告诉 Spring 使用 setter 注入。

        Spring 可以通过 2 种方式实现属性注入:构造函数注入和 setter 注入(又称设值注入)。

        *注:这里 Beans 配置文件保存为 spring-beans.xml,具体使用方式,参考 “”,下同。
        
    (2) 示例

  1         package com.example;
  2 
  3         import java.util.List;
  4         import java.util.Map;
  5         import java.util.Set;
  6         import java.util.Arrays;
  7 
  8         import org.springframework.context.support.ClassPathXmlApplicationContext;
  9         import org.springframework.context.ApplicationContext;
 10 
 11         public class App {
 12             public static void main( String[] args ) {
 13                 ApplicationContext context1 = new ClassPathXmlApplicationContext("spring-beans.xml");
 14                 Person person = (Person) context1.getBean("person");
 15                 person.display();
 16             }
 17         }
 18 
 19         class Man {
 20             String name;
 21             int age;
 22             private String dependValue;
 23 
 24             // 有其它有参构造函数,所以不要省略
 25             public Man() {
 26 
 27             }
 28 
 29             public Man(String name) {
 30                 this.name = name;
 31             }
 32 
 33             public void setDependValue(String dependValue) {
 34                 this.dependValue = dependValue;
 35             }
 36 
 37             public void display() {
 38                 System.out.println("Man -> display(): name = " + name
 39                                                     + ", age = " + age
 40                                                     + ", dependValue = " + dependValue);
 41             }
 42 
 43             public void setAge(int age) {
 44                 this.age = age;
 45             }
 46         }
 47 
 48         class Person {
 49             private Man man;
 50             private String nullValue;
 51             private String emptyValue;
 52             private String literalString;
 53             private String[] array;
 54             private List list;
 55             private Map map;
 56             private Set set;
 57 
 58             // 有其它有参构造函数,所以不要省略
 59             public Person() {
 60 
 61             }
 62 
 63             public Person(Man man) {
 64                 this.man = man;
 65             }
 66 
 67             // 使用级联属性 setter 注入,需提供一个依赖对象的 getXxx() 方法
 68             public Man getMan() {
 69                 return man;
 70             }
 71 
 72             public void display() {
 73                 man.display();
 74                 System.out.println("Person -> display(): nullValue = " + nullValue
 75                                                     + ", emptyValue = " + emptyValue
 76                                                     + ", literalString = " + literalString);
 77                 System.out.println("Person -> display(): array = " +  Arrays.toString(array));
 78                 System.out.println("Person -> display(): list = " + list);
 79                 System.out.println("Person -> display(): map = " + map);
 80                 System.out.println("Person -> display(): set = " + set);
 81             }
 82 
 83             public void setNullValue(String nullValue) {
 84                 this.nullValue = nullValue;
 85             }
 86 
 87             public void setEmptyValue(String emptyValue) {
 88                 this.emptyValue = emptyValue;
 89             }
 90 
 91             public void setLiteralString(String literalString) {
 92                 this.literalString = literalString;
 93             }
 94 
 95             public void setArray(String[] array) {
 96                 this.array = array;
 97             }
 98 
 99             public void setList(List list) {
100                 this.list = list;
101             }
102 
103             public void setMap(Map map) {
104                 this.map = map;
105             }
106 
107             public void setSet(Set set) {
108                 this.set = set;
109             }
110         }

2. 基于注解的配置方式

    (1) Beans 配置文件 (主配置文件)
    
        Spring 默认不使用注解装配 Bean,因此我们需要在 Spring 的 XML 配置中,通过 元素开启 Spring Beans的自动扫描功能。

 1         <?xml version="1.0" encoding="UTF-8"?>
 2          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-4.0.xsd
 7                                 http://www.springframework.org/schema/context
 8                                 http://www.springframework.org/schema/context/spring-context-4.0.xsd" >
 9 
10             package="com.example" />
11 
12         

        添加 标签,spring 就会去自动扫描 com.example 包内的 java 文件,如果扫描到文件中带有@Service, @Component, @Repository ,@Controller 等这些注解的类,则把这些类注册为 bean。

    (2) 示例

 1         package com.example;
 2 
 3         import java.util.List;
 4         import java.util.Map;
 5         import java.util.Set;
 6         import java.util.Arrays;
 7 
 8         import javax.annotation.Resource;
 9         import org.springframework.stereotype.Component;
10         import org.springframework.beans.factory.annotation.Value;
11 
12         import org.springframework.context.support.ClassPathXmlApplicationContext;
13         import org.springframework.context.ApplicationContext;
14 
15         public class App {
16             public static void main( String[] args ) {
17                 ApplicationContext context1 = new ClassPathXmlApplicationContext("spring-beans.xml");
18                 Person2 person2 = (Person2) context1.getBean("person2");
19                 person2.display();
20             }
21         }
22 
23         @Component("man2")
24         class Man2 {
25             @Value("Spring setter method")
26             String name;
27 
28             // 有其它有参构造函数,所以不要省略
29             public Man2() {
30 
31             }
32 
33             public Man2(String name) {
34                 this.name = name;
35             }
36 
37             public void display() {
38                 System.out.println("Man2 -> display(): name = " + name);
39             }
40         }
41 
42         @Component("person2")
43         class Person2 {
44             @Resource(name="man2")
45             private Man2 man2;
46 
47             private String nullValue;
48             @Value("")
49             private String emptyValue;
50             @Value("")
51             private String literalString;
52 
53             @Value("#{'1,2,3'.split(',')}")
54             private String[] array;
55             @Value("#{'\"Java\",\"Spring\",\"Idea\"'.split(',')}")
56             private List list;
57             @Value("#{'\"Tree\",\"Dog\",\"River\"'.split(',')}")
58             private Set set;
59             @Value("#{{\"name\":\"Tester\",\"age\": 21}}")
60             private Map map;
61 
62             // 有其它有参构造函数,所以不要省略
63             public Person2() {
64 
65             }
66 
67             public Person2(Man2 man2) {
68                 this.man2 = man2;
69             }
70 
71             public void display() {
72                 man2.display();
73                 System.out.println("Person2 -> display(): nullValue = " + nullValue
74                                                 + ", emptyValue = " + emptyValue
75                                                 + ", literalString = " + literalString);
76                 System.out.println("Person2 -> display(): array = " +  Arrays.toString(array));
77                 System.out.println("Person2 -> display(): list = " + list);
78                 System.out.println("Person2 -> display(): set = " + set);
79                 System.out.println("Person2 -> display(): map = " + map);
80             }
81         }