Spring基础知识(7)- Spring Bean (四)

2022/3/7 23:15:41

本文主要是介绍Spring基础知识(7)- Spring Bean (四),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Spring自动装配(基于配置文件)、Spring自动装配(基于注解)


1. Spring自动装配(基于配置文件)

    Spring 在 Bean 与 Bean 之间建立依赖关系的行为称为 “装配”。

    在 XML 配置中通过 <constructor-arg> 和 <property> 中的 ref 属性,手动维护 Bean 与 Bean 之间的依赖关系的。Spring 容器可以不使用 <constructor-arg> 和 <property> 元素的情况下自动装配相互协作的 bean 之间的关系。

    Spring 框架式默认不支持自动装配,需要对 Spring XML 配置文件中 <bean> 元素的 autowire 属性进行设置。

    Spring 共提供了 5 中自动装配规则,它们分别与 autowire 属性的 5 个取值对应,具体说明如下:

属性值 说明
byName 按名称自动装配,Spring 会根据的 Java 类中对象属性的名称,在整个应用的上下文 ApplicationContext(IoC 容器)中查找。若某个 Bean 的 id 或 name 属性值与这个对象属性的名称相同,则获取这个 Bean,并与当前的 Java 类 Bean 建立关联关系。
byType 按类型自动装配,Spring 会根据 Java 类中的对象属性的类型,在整个应用的上下文 ApplicationContext(IoC 容器)中查找。若某个 Bean 的 class 属性值与这个对象属性的类型相匹配,则获取这个 Bean,并与当前的 Java 类的 Bean 建立关联关系。
constructor 与 byType 模式相似,不同之处在与它应用于构造器参数(依赖项),如果在容器中没有找到与构造器参数类型一致的 Bean,那么将抛出异常。其实就是根据构造器参数的数据类型,进行 byType 模式的自动装配。
default 表示默认采用上一级元素 <beans> 设置的自动装配规则(default-autowire)进行装配。
no 默认值,表示不使用自动装配,Bean 的依赖关系必须通过 <constructor-arg>和 <property> 元素的 ref 属性来定义。


    1) 不使用自动装配 (autowire="no")

        autowire="no" 表示不使用自动装配, 此时要通过 <constructor-arg>和 <property> 元素的 ref 属性维护 Bean 的依赖关系。

        Spring 配置文件(spring-beans.xml)配置格式如下:

 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-4.0.xsd
 7                                     http://www.springframework.org/schema/context
 8                                     http://www.springframework.org/schema/context/spring-context-4.0.xsd"
 9                 default-autowire="constructor">
10 
11                 <bean id="group" class="com.example.Group">
12                     <property name="name" value="Group 1"></property>
13                     <property name="num" value="1"></property>
14                 </bean>
15                 <bean id="company" class="com.example.Company" autowire="no">
16                     <property name="name" value="Company 1"></property>
17                     <property name="group" ref="group"></property>
18                 </bean>
19 
20             </beans>


        示例:

 1             package com.example;
 2 
 3             import org.springframework.context.support.ClassPathXmlApplicationContext;
 4 
 5             public class AutowireApp {
 6                 public static void main( String[] args ) {
 7 
 8                     ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-beans.xml");
 9                     Company company = context.getBean("company", Company.class);
10                     company.display();
11 
12                 }
13             }
14 
15             class Group {
16                 private String name;
17                 private int num;
18 
19                 public Group() {
20                     System.out.println("Group -> Group()");
21                 }
22                 public Group(String name, int num) {
23                     System.out.println("Group -> Group(String name, int num)");
24                     this.name = name;
25                     this.num = num;
26                 }
27 
28                 public void setName(String name) {
29                     System.out.println("Group -> setName('" + name+ "')");
30                     this.name = name;
31                 }
32 
33                 public void setNum(int num) {
34                     System.out.println("Group -> setNum('" + num + "')");
35                     this.num = num;
36                 }
37 
38                 public String getName() {
39                     return name;
40                 }
41 
42                 public int getNum() {
43                     return num;
44                 }
45 
46                 public void display() {
47                     System.out.println("Group -> display(): name = " + name
48                                                     + ", num = " + num);
49                 }
50 
51             }
52 
53             class Company {
54                 private String name;
55                 private Group group;
56 
57                 public Company() {
58                     System.out.println("Company -> Company()");
59                 }
60                 public Company(String name, Group group) {
61                     System.out.println("Company -> Company(String name, Group group)");
62                     this.name = name;
63                     this.group = group;
64                 }
65 
66                 public void setName(String name) {
67                     System.out.println("Company -> setName('" + name+ "')");
68                     this.name = name;
69                 }
70 
71                 public void setGroup(Group group) {
72                     System.out.println("Company -> setGroup()");
73                     this.group = group;
74                 }
75 
76                 public void display() {
77                     System.out.println("Company -> display(): name = " + name
78                                                     + ", group.getName() = " + group.getName()
79                                                     + ", group.getNum() = " + group.getNum());
80                 }
81 
82             }


        输出:

            Group -> Group()
            Group -> setName('Group 1')
            Group -> setNum('1')
            Company -> Company()
            Company -> setName('Company 1')
            Company -> setGroup()
            Company -> display(): name = Company 1, group.getName() = Group 1, group.getNum() = 1

    2) 按属性名称自动装配(autowire="byName")

        autowire="byName" 表示按属性名称自动装配,XML 文件中 Bean 的 id 或 name 必须与类中的属性名称相同。

        Spring 配置文件(spring-beans.xml)配置格式如下:

 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-4.0.xsd
 7                                     http://www.springframework.org/schema/context
 8                                     http://www.springframework.org/schema/context/spring-context-4.0.xsd">
 9 
10                 <bean id="group" class="com.example.Group">
11                     <property name="name" value="Group 2"></property>
12                     <property name="num" value="2"></property>
13                 </bean>
14                 <bean id="company" class="com.example.Company" autowire="byName">
15                     <property name="name" value="Company 2"></property>
16                 </bean>
17 
18             </beans>


        示例

            与 “1) 不使用自动装配” 的代码一样

        输出:

            Group -> Group()
            Group -> setName('Group 2')
            Group -> setNum('2')
            Company -> Company()
            Company -> setName('Company 2')
            Company -> setGroup()
            Company -> display(): name = Company 2, group.getName() = Group 2, group.getNum() = 2

    3) 按类型自动装配(autowire="byType")

        autowire="byType" 表示按类中对象属性数据类型进行自动装配。即使 XML 文件中 Bean 的 id 或 name 与类中的属性名不同,只要 Bean 的 class 属性值与类中的对象属性的类型相同,就可以完成自动装配。

        Spring 配置文件(spring-beans.xml)配置格式如下:

 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-4.0.xsd
 7                                     http://www.springframework.org/schema/context
 8                                     http://www.springframework.org/schema/context/spring-context-4.0.xsd">
 9 
10                 <bean id="group" class="com.example.Group">
11                     <property name="name" value="Group 3"></property>
12                     <property name="num" value="3"></property>
13                 </bean>
14                 <bean id="company" class="com.example.Company" autowire="byType">
15                     <property name="name" value="Company 3"></property>
16                 </bean>
17 
18             </beans>  


        示例:

            与 “1) 不使用自动装配” 的代码一样

        输出:

            Group -> Group()
            Group -> setName('Group 3')
            Group -> setNum('3')
            Company -> Company()
            Company -> setName('Company 3')
            Company -> setGroup()
            Company -> display(): name = Company 3, group.getName() = Group 3, group.getNum() = 3

    4) 构造函数自动装配(autowire="constructor")

        autowire="constructor" 表示按照 Java 类中构造函数进行自动装配。

        Spring 配置文件(spring-beans.xml)配置格式如下:

 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-4.0.xsd
 7                                     http://www.springframework.org/schema/context
 8                                     http://www.springframework.org/schema/context/spring-context-4.0.xsd">
 9 
10                 <bean id="group" class="com.example.Group">
11                     <constructor-arg name="name" value="Group 4"></constructor-arg>
12                     <constructor-arg name="num" value="4"></constructor-arg>                    
13                 </bean>
14                 <bean id="company" class="com.example.Company" autowire="constructor">
15                     <constructor-arg name="name" value="Company 4"></constructor-arg>
16                 </bean>
17 
18             </beans> 


        示例:

            与 “1) 不使用自动装配” 的代码一样

        输出:

            Group -> Group(String name, int num)
            Company -> Company(String name, Group group)
            Company -> display(): name = Company 4, group.getName() = Group 4, group.getNum() = 4

    5) 默认的自动装配模式(autowire="default")

        默认采用上一级标签 <beans> 设置的自动装配规则(default-autowire)进行装配。

        Spring 配置文件(spring-beans.xml)配置格式如下:

 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-4.0.xsd
 7                                     http://www.springframework.org/schema/context
 8                                     http://www.springframework.org/schema/context/spring-context-4.0.xsd"
 9                 default-autowire="byType">
10 
11                 <bean id="group" class="com.example.Group">
12                     <property name="name" value="Group 5"></property>
13                     <property name="num" value="5"></property>
14                 </bean>
15                 <bean id="company" class="com.example.Company" autowire="default">
16                     <property name="name" value="Company 5"></property>
17                 </bean>
18 
19             </beans> 


        示例:

            与 “1) 不使用自动装配” 的代码一样

        输出:

            Group -> Group()
            Group -> setName('Group 5')
            Group -> setNum('5')
            Company -> Company()
            Company -> setName('Company 5')
            Company -> setGroup()
            Company -> display(): name = Company 5, group.getName() = Group 5, group.getNum() = 5

2. Spring自动装配(基于注解)

    从 Java 5 开始,Java 增加了对注解(Annotation)的支持,它是代码中的一种特殊标记,可以在编译、类加载和运行时被读取,执行相应的处理。开发人员可以通过注解在不改变原有代码和逻辑的情况下,在源代码中嵌入补充信息。

    Spring 从 2.5 版本开始提供了对注解技术的全面支持,我们可以使用注解来实现自动装配,简化 Spring 的 XML 配置。

    1) 开启组件扫描

        Spring 配置文件(spring-beans.xml),配置格式如下:

 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-4.0.xsd
 7                                                 http://www.springframework.org/schema/context
 8                                                 http://www.springframework.org/schema/context/spring-context-4.0.xsd">
 9 
10                     <context:component-scan base-package="com.example"/>
11 
12             </beans>


    2) 使用注解定义 Bean

        Spring 提供了以下多个注解,这些注解可以直接标注在 Java 类上,将它们定义成 Spring Bean。

注解 说明
@Component 该注解用于描述 Spring 中的 Bean,它是一个泛化的概念,仅仅表示容器中的一个组件(Bean),并且可以作用在应用的任何层次,例如 Service 层、Dao 层等。
@Repository 该注解用于将数据访问层(Dao 层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Service 该注解通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Controller 该注解通常作用在控制层(如 Struts2 的 Action、SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。


3) 属性注入

注解 说明
@Autowired 可以应用到 Bean 的属性变量、setter 方法、非 setter 方法及构造函数等,默认按照 Bean 的类型进行装配。
@Resource 作用与 Autowired 相同,区别在于 @Autowired 默认按照 Bean 类型装配,而 @Resource 默认按照 Bean 的名称进行装配。
@Qualifier 与 @Autowired 注解配合使用,会将默认的按 Bean 类型装配修改为按 Bean 的实例名称装配,Bean 的实例名称由 @Qualifier 注解的参数指定。


    示例:

 1         package com.example;
 2 
 3         import org.springframework.context.support.ClassPathXmlApplicationContext;
 4         import javax.annotation.Resource;
 5         import org.springframework.stereotype.Component;
 6         import org.springframework.beans.factory.annotation.Value;
 7 
 8         public class App {
 9             public static void main( String[] args ) {
10 
11                 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-beans.xml");
12                 CompanyA companyA = context.getBean("companyA", CompanyA.class);
13                 companyA.display();
14 
15             }
16         }
17 
18         @Component("groupA")
19         class GroupA {
20             @Value("Group 6")
21             private String name;
22             @Value("6")
23             private int num;
24 
25             public GroupA() {
26                 System.out.println("GroupA -> GroupA()");
27             }
28 
29             public String getName() {
30                 return name;
31             }
32 
33             public int getNum() {
34                 return num;
35             }
36 
37             public void display() {
38                 System.out.println("GroupA -> display(): name = " + name
39                         + ", num = " + num);
40             }
41 
42         }
43 
44         @Component("companyA")
45         class CompanyA {
46             @Value("Company 6")
47             private String name;
48             @Resource(name="groupA")
49             private GroupA group;
50 
51             public CompanyA() {
52                 System.out.println("CompanyA -> CompanyA()");
53             }
54 
55             public void display() {
56                 System.out.println("CompanyA -> display(): name = " + name
57                         + ", group.getName() = " + group.getName()
58                         + ", group.getNum() = " + group.getNum());
59             }
60 
61         }


    输出:

        CompanyA -> CompanyA()
        GroupA -> GroupA()
        CompanyA -> display(): name = Company 6, group.getName() = Group 6, group.getNum() = 6



这篇关于Spring基础知识(7)- Spring Bean (四)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程