1. 自动配置
1.1 什么是依赖自动装配?
- IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
1.2 自动装配方式有哪些?
- 按类型(常用)
- 按名称
- 按构造方法
- 不启用自动装配
1.3 准备下案例环境
- 创建一个Maven项目
- pom.xml添加依赖
- resources下添加spring的配置文件
项目的结构如下:
(1)项目中添加UserDao、UserDaoImpl、UserService和UserServiceImpl类
public interface UserDao {
public void select();
}
public class UserDaoImpl implements UserDao {
private String userName;
private Integer userAge;
public void select() {
System.out.println("UserDao select, running ......");
}
}
public interface UserService {
public void select();
}
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void select() {
System.out.println("UserService select, running ......");
userDao.select();
}
}
(2)resources下提供spring的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.dcxuexi.dao.impl.UserDaoImpl" />
<bean id="userService" class="com.dcxuexi.service.impl.UserServiceImpl" >
<property name="userDao" ref="userDao" />
</bean>
</beans>
(3)编写AppForAutoware运行类,加载Spring的IOC容器,并从中获取对应的bean对象
public class SpringAnto {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) context.getBean("userService");
userService.select();
}
}
1.4 完成自动装配的配置
接下来,在上面这个环境中来完成自动装配
的学习:
自动装配只需要修改applicationContext.xml配置文件即可:
(1)将<property>
标签删除
(2)在<bean>
标签中添加autowire属性
首先来实现按照类型注入的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.dcxuexi.dao.impl.UserDaoImpl" />
<!--autowire属性:开启自动装配,通常使用按类型装配-->
<bean id="userService" class="com.dcxuexi.service.impl.UserServiceImpl" autowire="byType" />
</beans>
注意事项:
- 需要注入属性的类中对应属性的setter方法不能省略
- 被注入的对象必须要被Spring的IOC容器管理
- 按照类型在Spring的IOC容器中如果找到多个对象,会报
NoUniqueBeanDefinitionException
一个类型在IOC中有多个对象,还想要注入成功,这个时候就需要按照名称注入,配置方式为:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.dcxuexi.dao.impl.UserDaoImpl" />
<!--autowire属性:开启自动装配,通常使用按类型装配-->
<bean id="userService" class="com.dcxuexi.service.impl.UserServiceImpl" autowire="byName" />
</beans>
注意事项:
- 按照名称注入中的名称指的是什么?
- userDao是private修饰的,外部类无法直接方法
- 外部类只能通过属性的set方法进行访问
- 对外部类来说,setUserDao方法名,去掉set后首字母小写是其属性名
- 为什么是去掉set首字母小写?
- 这个规则是set方法生成的默认规则,set方法的生成是把属性名首字母大写前面加set形成的方法名
- 所以按照名称注入,其实是和对应的set方法有关,但是如果按照标准起名称,属性名和set对应的名是一致的
- 如果按照名称去找对应的bean对象,找不到则注入Null
- 当某一个类型在IOC容器中有多个对象,按照名称注入只找其指定名称对应的bean对象,不会报错
两种方式介绍完后,以后用的更多的是按照类型注入。
最后对于依赖注入,需要注意一些其他的配置特征:
- 自动装配用于引用类型依赖注入,不能对简单类型进行操作
- 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
- 使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
- 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
2. 集合注入
前面我们已经能完成引入数据类型和简单数据类型的注入,但是还有一种数据类型集合,集合中既可以装简单数据类型也可以装引用数据类型,对于集合,在Spring中该如何注入呢?
先来回顾下,常见的集合类型有哪些?
- 数组
- List
- Set
- Map
- Properties
针对不同的集合类型,该如何实现注入呢?
2.1 环境准备
- 创建一个Maven项目
- pom.xml添加依赖
- resources下添加spring的配置文件applicationContext.xml
项目的结构如下:
(1)项目中添加添加UserDao、UserDaoImpl类
public interface UserDao {
public void select();
}
public class UserDaoImpl implements UserDao {
private int[] array;
private Set<String> set;
private List<String> list;
private Map<String,String> map;
private Properties properties;
public void setArray(int[] array) {
this.array = array;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setList(List<String> list) {
this.list = list;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public void select() {
System.out.println("UserDao select, running .....");
System.out.println("array = " + Arrays.toString(array));
System.out.println("set = " + set);
System.out.println("list = " + list);
System.out.println("map = " + map);
System.out.println("properties = "+ properties);
}
}
(2)resources下提供spring的配置文件,applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.dcxuexi.dao.impl.UserDaoImpl" />
</beans>
(3)编写SpringCollection运行类,加载Spring的IOC容器,并从中获取对应的bean对象
public class SpringCollection {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) context.getBean("userDao");
userDao.select();
}
}
接下来,在上面这个环境中来完成集合注入
的学习:
下面的所以配置方式,都是在userDao的bean标签中使用进行注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.dcxuexi.dao.impl.UserDaoImpl" >
</bean>
</beans>
2.2 注入数组类型数据
<property name="array">
<array>
<value>1</value>
<value>2</value>
<value>3</value>
</array>
</property>
2.3 注入List类型数据
<property name="list">
<list>
<value>blue</value>
<value>red</value>
<value>green</value>
</list>
</property>
2.4 注入Set类型数据
<property name="set">
<set>
<value>zhangsan</value>
<value>lisi</value>
<value>wangwu</value>
</set>
</property>
2.5 注入Map类型数据
<property name="map">
<map>
<entry key="name" value="xiaochuang" />
<entry key="age" value="20" />
<entry key="address" value="shanghai" />
</map>
</property>
2.6 注入Properties类型数据
<property name="properties">
<props>
<prop key="ip">192.168.1.110</prop>
<prop key="port">18080</prop>
</props>
</property>
完整注入的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.dcxuexi.dao.impl.UserDaoImpl" >
<property name="array">
<array>
<value>1</value>
<value>2</value>
<value>3</value>
</array>
</property>
<property name="set">
<set>
<value>zhangsan</value>
<value>lisi</value>
<value>wangwu</value>
</set>
</property>
<property name="list">
<list>
<value>blue</value>
<value>red</value>
<value>green</value>
</list>
</property>
<property name="map">
<map>
<entry key="name" value="xiaochuang" />
<entry key="age" value="20" />
<entry key="address" value="shanghai" />
</map>
</property>
<property name="properties">
<props>
<prop key="ip">192.168.1.110</prop>
<prop key="port">18080</prop>
</props>
</property>
</bean>
</beans>
配置完成后,运行下看结果:
说明:
- property标签表示setter方式注入,构造方式注入constructor-arg标签内部也可以写
<array>
、<list>
、<set>
、<map>
、<props>
标签 - List的底层也是通过数组实现的,所以
<list>
和<array>
标签是可以混用 - 集合中要添加引用类型,只需要把
<value>
标签改成<ref>
标签,这种方式用的比较少