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
标签:Group,name,Spring,Company,基础知识,Bean,group 来源: https://www.cnblogs.com/tkuang/p/15978215.html