一、自动装配
如果一个bean里有很多属性,每个属性都要手动加property节点显式注入属性值,就显得十分麻烦。在基于XML配置元数据时,可以使用bean元素的autowire属性来指定具体的自动装配模式。
使用Autowire去除<property>标签有两种方式:
- 可以配置在<beans>根标签下,表示对全局<bean>起作用,属性名为default-autowire
- 可以配置在<bean>标签下,表示对当前<bean>起作用,属性名为autowire
autowire属性主要有以下几种值:
属性 | 说明 |
---|---|
no | 默认设置,意味着它没有使用自动装配模式。 |
byName | 由属性名自动装配。Spring 容器看到bean采用了自动装配byName模式(autowire="byName"),然后根据它的属性在Spring 容器中寻找与属性名相同bean进行关联 |
byType | 由属性的数据类型自动装配。Spring容器看到bean采用了自动装配的byType模式(autowire="byType"),然后根据属性类型在Spring容器中寻找与属性类型相同bean进行关联。如果存在不止一个这样的bean,将抛出异常。 |
constructor | 类似于 byType,但该类型适用于构造函数参数类型。如果在容器中没有一个构造函数参数类型的 bean,则一个致命错误将会发生 |
接下来我们通过案例来演示一下byName和byType的使用:
(1)分别创建Staff和Department类
public class Staff {
private String name;
private Department department;
public void setName(String name) {
this.name = name;
}
public void setDepartment(Department department) {
this.department = department;
}
@Override
public String toString() {
return "Staff{" +
"name='" + name + '\'' +
", department=" + department +
'}';
}
}
public class Department {
private String dName;
public void setdName(String dName) {
this.dName = dName;
}
@Override
public String toString() {
return "Department{" +
"dName='" + dName + '\'' +
'}';
}
}
(2)在bean.xml中进行配置
<!-- 手动装配 -->
<bean id="staff1" class="com.yht.example3.entity.Staff">
<property name="name" value="张三"></property>
<property name="department" ref="department"></property>
</bean>
<bean id="department" class="com.yht.example3.entity.Department">
<property name="dName" value="技术部"></property>
</bean>
<!-- 自动装配 byName -->
<bean id="staff2" class="com.yht.example3.entity.Staff" autowire="byName">
<property name="name" value="李四"></property>
</bean>
<!-- 自动装配 byType -->
<bean id="staff3" class="com.yht.example3.entity.Staff" autowire="byType">
<property name="name" value="王五"></property>
</bean>
(3)进行单元测试
@Test
public void testAutowired(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Staff staff1 = context.getBean("staff1", Staff.class);//手动装配
Staff staff2 = context.getBean("staff2", Staff.class);//自动装配 byName
Staff staff3 = context.getBean("staff3", Staff.class);//自动装配 byType
System.out.println(staff1);
System.out.println(staff2);
System.out.println(staff3);
}
执行结果如下:
关于byType的说明:
如果使用byType进行自动装配,则同类型的实例对象在bean.xml中只能有一个,否则就会报错。
解决办法:当发现出现多个同类型的bean对象,可以将其中一个设置primary属性,作为优先选择的对象。如下:
<bean id="department2" class="com.yht.example3.entity.Department" primary="true">
<property name="dName" value="财务部"></property>
</bean>
执行结果如下:
需要注意的是:即便使用了primary,但bean.xml依旧会有错误提示。所以遇到这种情况,尽量排除其中无用的bean对象。
二、外部属性文件
通常在遇到一些公共数据或者全局数据时,都会配置到外部文件中,然后在xml读取外部文件中的内容,这里以数据库的配置为例:
首先,引入Druid连接池依赖 jar 包
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.22</version>
</dependency>
1、直接配置的方式
<!--直接配置连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/test"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
2、外部文件的方式
(1)创建外部属性文件,后缀为properties,写入数据库信息
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.userName=root
jdbc.password=root
(2)引入 context 名称空间
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--引入context名称空间-->
<!--引入外部属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClass}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.userName}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
</beans>