这里写目录标题
- 1. setter注入
- 在一个类中注入引用类型
- 在一个类中注入简单类型
- 2. 构造器注入
- 在一个类中注入引用类型
- 在一个类中注入简单类型
- 3. 依赖注入方式选择
- 4. 依赖自动装配
- 按类型注入
- 按名称注入
- 5. 集合注入
1. setter注入
在一个类中注入引用类型
回顾一下之前setter注入的方法,我们有以下类:
BookDao.java
package com.example.demo.dao;
public interface BookDao {
void save();
}
BookDaoImpl.java
package com.example.demo.dao.impl;
import com.example.demo.dao.BookDao;
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println("book dao save...");
}
}
BookService.java
package com.example.demo.service;
public interface BookService {
void save();
}
BookServiceImpl.java
package com.example.demo.service.impl;
import com.example.demo.dao.BookDao;
import com.example.demo.service.BookService;
public class BookServiceImpl implements BookService {
private BookDao bookDao;
@Override
public void save() {
System.out.println("book service save...");
}
}
我们想要将BookDaoImpl
注入到BookServiceImpl
中,最简单的方法就是通过setter注入
第一步: 在BookServiceImpl
中建立bookDao
的setter
方法:
package com.example.demo.service.impl;
import com.example.demo.dao.BookDao;
import com.example.demo.service.BookService;
public class BookServiceImpl implements BookService {
private BookDao bookDao;
@Override
public void save() {
System.out.println("book service save...");
}
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
第二步: 配置bookDao,和bookService两个bean(在resource下建立Spring Config文件):
<?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="com.example.demo.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.example.demo.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao" />
</bean>
</beans>
id
属性为bean的名称,class
为对应需要注入的类
property
表示类里面需要注入的属性,name
是属性名称,ref
是属性的引用类,这里引用的是上面的bookDao
类
以上两步即可完成配置,测试一下:
package com.example.demo.service.impl;
import com.example.demo.dao.BookDao;
import com.example.demo.service.BookService;
public class BookServiceImpl implements BookService {
private BookDao bookDao;
@Override
public void save() {
System.out.println("book service save...");
bookDao.save();
}
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
结果是:
book service save...
book dao save...
在一个类中注入简单类型
假如在上面的BookDaoImpl.java
中,还有两个简单类型:
package com.example.demo.dao.impl;
import com.example.demo.dao.BookDao;
public class BookDaoImpl implements BookDao {
private int connectNum;
private String databaseName;
@Override
public void save() {
System.out.println("book dao save...");
System.out.println("connectNum:" + connectNum + ", databaseName:" + databaseName);
}
}
第一步: 如果使用setter注入,首先给这两个简单类型写set方法:
public void setConnectNum(int connectNum) {
this.connectNum = connectNum;
}
public void setDatabaseName(String databaseName) {
this.databaseName = databaseName;
}
第二步: 配置的时候,bookDao
的配置应该这样写:
<bean id="bookDao" class="com.example.demo.dao.impl.BookDaoImpl">
<property name="connectNum" value="10"/>
<property name="databaseName" value="name" />
</bean>
name
表示属性的名字,value
表示赋予简单类型的值
再执行一下上面写的测试主方法(此处略),结果为:
book service save...
book dao save...
connectNum:10, databaseName:name
总结简单类型的注入:
2. 构造器注入
在一个类中注入引用类型
BookDao.java
package com.example.demo.dao;
public interface BookDao {
void save();
}
BookDaoImpl.java
package com.example.demo.dao.impl;
import com.example.demo.dao.BookDao;
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println("book dao save...");
}
}
BookService.java
package com.example.demo.service;
public interface BookService {
void save();
}
BookServiceImpl.java
package com.example.demo.service.impl;
import com.example.demo.dao.BookDao;
import com.example.demo.service.BookService;
public class BookServiceImpl implements BookService {
private BookDao bookDao;
@Override
public void save() {
System.out.println("book service save...");
}
}
我们想使用构造器注入在bookServiceImpl
中注入bookDao
,方法如下:
第一步: 在bookServiceImpl中写构造方法
public BookServiceImpl(BookDao bookDao) {
this.bookDao = bookDao;
}
第二步: 在配置中配置有参构造方法,通过constructor-arg
标签进行构造,也就是向bookDao类型中传入一个什么样的参数
<?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="com.example.demo.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.example.demo.service.impl.BookServiceImpl">
<constructor-arg name="bookDao" ref="bookDao"/>
</bean>
</beans>
再运行主方法,可以获得一样的结果:
book service save...
book dao save...
同样的,假如我们还有一个UserDaoImpl
:
UserDao.java:
package com.example.demo.dao;
public interface UserDao {
void save();
}
UserDaoImpl.java:
package com.example.demo.dao.impl;
import com.example.demo.dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("user dao save...");
}
}
我们在BookServiceImpl
中还引入了这个类型:
package com.example.demo.service.impl;
import com.example.demo.dao.BookDao;
import com.example.demo.dao.UserDao;
import com.example.demo.service.BookService;
public class BookServiceImpl implements BookService {
private BookDao bookDao;
private UserDao userDao;
public BookServiceImpl(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void save() {
System.out.println("book service save...");
bookDao.save();
userDao.save();
}
}
则需要重新写一下构造方法:
public BookServiceImpl(BookDao bookDao, UserDao userDao) {
this.bookDao = bookDao;
this.userDao = userDao;
}
并多加一行对userDao的配置:
<?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="com.example.demo.dao.impl.BookDaoImpl"/>
<bean id="userDao" class="com.example.demo.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.example.demo.service.impl.BookServiceImpl">
<constructor-arg name="bookDao" ref="bookDao"/>
<constructor-arg name="userDao" ref="userDao"/>
</bean>
</beans>
再次运行测试函数,结果如下:
book service save...
book dao save...
user dao save...
在一个类中注入简单类型
BookDao
代码如下:
package com.example.demo.dao.impl;
import com.example.demo.dao.BookDao;
public class BookDaoImpl implements BookDao {
private int connectNum;
private String databaseName;
@Override
public void save() {
System.out.println("book dao save...");
}
}
想要给两个简单类型属性做配置,方法都是一样的:
第一步: 创建构造方法
package com.example.demo.dao.impl;
import com.example.demo.dao.BookDao;
public class BookDaoImpl implements BookDao {
private int connectNum;
private String databaseName;
public BookDaoImpl(int connectNum, String databaseName) {
this.connectNum = connectNum;
this.databaseName = databaseName;
}
@Override
public void save() {
System.out.println("book dao save...");
System.out.println("connectNum:" + connectNum + ", databaseName:" + databaseName);
}
}
第二步: 配置属性
<?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="com.example.demo.dao.impl.BookDaoImpl">
<constructor-arg name="connectNum" value="10"/>
<constructor-arg name="databaseName" value="aaa"/>
</bean>
<bean id="userDao" class="com.example.demo.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.example.demo.service.impl.BookServiceImpl">
<constructor-arg name="bookDao" ref="bookDao"/>
<constructor-arg name="userDao" ref="userDao"/>
</bean>
</beans>
运行后结果为:
book service save...
book dao save...
connectNum:10, databaseName:aaa
user dao save...
除了通过name指定配置的参数,还有两种办法指定:
我们上面通过name指定的是标准写法
第一种是通过参数类型进行指定(是为了解耦,避免配置和name耦合)
第二种是通过参数位置进行指定(为了解决有同样类型的参数的问题)
3. 依赖注入方式选择
建议使用setter注入
第三方技术根据情况选择
4. 依赖自动装配
定义:
注意,想要让IoC容器实现自动装配,必须给这些属性配置setter方法!
按类型注入
这些属性的类型要能够在配置的bean中的类型对应的上:
假如配置了两个指向同一类型,id不同的bean,显而易见bookService那里已经报红了:
如果仍让执行报错会提示,找到了两个bean,不知道匹配哪一个:
所以bean的类型指向必须唯一!
按名称注入
这些属性的名称要能够在配置的bean中的id对应的上:
5. 集合注入
假设我们的BookDaoImpl.java
中有以下的数据类型
package com.example.demo.dao.impl;
import com.example.demo.dao.BookDao;
import java.util.*;
public class BookDaoImpl implements BookDao {
private int[] array;
private List<String> list;
private Set<String> set;
private Map<String, String> map;
private Properties properties;
@Override
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 setProperties(Properties properties) {
this.properties = properties;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setList(List<String> list) {
this.list = list;
}
public void setArray(int[] array) {
this.array = array;
}
}
配置文件如下写:
<bean id="bookDao" class="com.example.demo.dao.impl.BookDaoImpl">
<property name="array">
<array>
<value>100</value>
<value>200</value>
<value>300</value>
</array>
</property>
<property name="list">
<list>
<value>a</value>
<value>b</value>
<value>c</value>
</list>
</property>
<property name="set">
<set>
<value>c</value>
<value>c</value>
<value>d</value>
</set>
</property>
<property name="map">
<map>
<entry key="country" value="china" />
<entry key="province" value="guangdong" />
<entry key="city" value="shenzhen" />
</map>
</property>
<property name="properties">
<props>
<prop key="country">china</prop>
<prop key="province">henan</prop>
<prop key="city">kaifeng</prop>
</props>
</property>
</bean>
set是会自动过滤重复元素的,结果如下:
book service save...
book dao save...
遍历数组:[100, 200, 300]
遍历List:[a, b, c]
遍历set:[c, d]
遍历Map:{country=china, province=guangdong, city=shenzhen}
遍历properties:{country=china, province=henan, city=kaifeng}
如果数组里面是引用类型,写法就是:
<property name="array">
<array>
<ref bean="beanId" />
</array>
</property>