依赖自动装配
在前文我们所提到的setter注入、构造器注入都需要配置,在我看来是有点麻烦的,为了简化我们的代码、提高我们的效率,我们可以使用依赖自动装配,那么什么是依赖自动装配呢?
IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
自动装配存在以下几种方式:
- 按类型(常用)
- 按名称
- 按构造方法(很少用我们不去了解)
- 不启用自动装配
接下来我们还是借用前文的工程结构来做两个实验:
在前文中:
我们的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="bookDao" class="impl.BookDaoImpl"/>
<bean id="bookService" class="impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
BookServiceImpl类:
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
App:
public class App2 {
public static void main(String[] args) {
//获取容器
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookService bookService = (BookService) ctx.getBean("bookService");
bookService.save();
}
}
接下来我们使用自动装配:
首先我们将<property>
标签删除,然后在<bean>
标签中添加autowire属性:
<bean id="bookDao" name="bookBookDao" class="impl.BookDaoImpl"/>
<!--autowire属性:开启自动装配,通常使用按类型装配-->
<bean id="bookService" class="impl.BookServiceImpl" scope="prototype" autowire="byType"/>
接下来我们在运行App2,结果正常:
注意:
①需要注入属性的类中对应属性的setter方法不能省略,并且要有空参构造器(因为该类首先是通过构造器进行bean的创建,再去进行依赖注入,而通过构造器创建则必须保证该类有一个空参构造器)
②被注入的对象必须要被Spring的IOC容器管理
③按照类型在Spring的IOC容器中如果找到多个对象,会报NoUniqueBeanDefinitionException
也就是说如果使用byType,那么容器中有且仅有一个bean的类型与之对应,否则就会报错!
那么假如真有两个bean的类型都满足怎么办呢?(当然这种情况很少发生,byType可以放心使用)
我们可以使用:byName
<bean id="bookDao" name="bookBookDao" class="impl.BookDaoImpl"/>
<bean id="bookService" class="impl.BookServiceImpl" scope="prototype" autowire="byName"/>
注意事项:
-
按照名称注入中的名称指的是什么?
- bookDao是private修饰的,外部类无法直接方法
- 外部类只能通过属性的set方法进行访问
- 对外部类来说,setBookDao方法名,去掉set后首字母小写是其属性名
- 为什么是去掉set首字母小写?
- 这个规则是set方法生成的默认规则,set方法的生成是把属性名首字母大写前面加set形成的方法名
- 所以按照名称注入,其实是和对应的set方法有关,但是如果按照标准起名称,属性名和set对应的名是一致的
-
如果按照名称去找对应的bean对象,找不到则注入Null
-
当某一个类型在IOC容器中有多个对象,按照名称注入只找其指定名称对应的bean对象,不会报错
最后对于依赖注入,需要注意一些其他的配置特征:
- 自动装配用于引用类型依赖注入,不能对简单类型进行操作
- 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
- 使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
- 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
集合注入
前面我们已经能完成引入数据类型和简单数据类型的注入,但是还有一种数据类型集合,集合中既可以装简单数据类型也可以装引用数据类型,对于集合,在Spring中该如何注入呢?
我们从以下几个方面入手:
- 数组
- List
- Set
- Map
- Properties
项目准备:
实现了BookDao接口的BookDaoImpl:
public class BookDaoImpl implements BookDao {
private int[] array;
private List<String> list;
private Set<String> set;
private Map<String,String> map;
private Properties properties;
public void save() {
System.out.println("book dao save ...");
System.out.println("遍历数组:" + Arrays.toString(array));
System.out.println("遍历List" + list);
System.out.println("遍历Set" + set);
System.out.println("遍历Map" + map);
System.out.println("遍历Properties" + properties);
}
public void setArray(int[] array) {
this.array = array;
}
public void setList(List<String> list) {
this.list = list;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
}
App3:
public class AppForDICollection {
public static void main( String[] args ) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
}
}
注入数组类型数据
<property name="array">
<array>
<value>100</value>
<value>200</value>
<value>300</value>
</array>
</property>
注入List类型数据
<property name="list">
<list>
<value>book</value>
<value>apple</value>
<value>fenda</value>
<value>banana</value>
</list>
</property>
注入Set类型数据
<property name="set">
<set>
<value>cat</value>
<value>car</value>
<value>cupple</value>
<value>cola</value>
</set>
</property>
注入Map类型数据
<property name="map">
<map>
<entry key="country" value="china"/>
<entry key="province" value="henan"/>
<entry key="city" value="kaifeng"/>
</map>
</property>
注入Properties类型数据
<property name="properties">
<props>
<prop key="country">china</prop>
<prop key="province">henan</prop>
<prop key="city">kaifeng</prop>
</props>
</property>
然后我们运行App3:
注意:
①property标签表示setter方式注入,构造方式注入constructor-arg标签内部也可以写<array>
、<list>
、<set>
、<map>
、<props>
标签
List的底层也是通过数组实现的,所以<list>
和<array>
标签是可以混用
集合中要添加引用类型,只需要把<value>
标签改成<ref>
标签,这种方式用的比较少
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/122089.html