SpringIoc注入
Spring IOC 手动装配(注入)
Spring 支持的注入方式共有四种:set 注入、构造器注入、静态工厂注入、实例化工厂注入。
set方法注入
注:
属性字段需要提供set方法
四种方式,推荐使用set方法注入
业务对象 JavaBean
- 属性字段提供set方法
1 2 3 4 5 6 7 8
| public class UserService {
private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } }
|
public class UserService {
// 业务对象UserDao set注入(提供set方法)
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
配置文件的bean标签设置property标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.xxxx.dao.UserDao"></bean> <bean id="userService" class="com.xxxx.service.UserService"> <property name="userDao" ref="userDao"/> </bean> </beans>
|
常用对象和基本类型
1.属性字段提供set方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class UserService {
private String host; public void setHost(String host) { this.host = host; }
private Integer port; public void setPort(Integer port) { this.port = port; } }
|
2.配置文件的bean标签设置property标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userService" class="com.xxxx.service.UserService"> <property name="host" value="127.0.0.1"/> <property name="port" value="8080"/> </bean>
</beans>
|
集合类型和属性对象
1.属性字段提供set方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class UserService {
public List<String> list; public void setList(List<String> list) { this.list = list; }
private Set<String> set; public void setSet(Set<String> set) { this.set = set; }
private Map<String,Object> map; public void setMap(Map<String, Object> map) { this.map = map; }
private Properties properties; public void setProperties(Properties properties) { this.properties = properties; } }
|
2.配置文件的bean标签设置property标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| <?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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<property name="list"> <list> <value>上海</value> <value>北京</value> <value>杭州</value> </list> </property>
<property name="set"> <set> <value>上海SH</value> <value>北京BJ</value> <value>杭州HZ</value> </set> </property>
<property name="map"> <map> <entry> <key><value>周杰伦</value></key> <value>我是如此相信</value> </entry> <entry> <key><value>林俊杰</value></key> <value>可惜没如果</value> </entry> <entry> <key><value>陈奕迅</value></key> <value>十年</value> </entry> </map> </property>
<property name="properties"> <props> <prop key="上海">东方明珠</prop> <prop key="北京">天安门</prop> <prop key="杭州">西湖</prop> </props> </property>
</beans>
|
多个Bean对象作为参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class UserService {
private UserDao userDao; private AccountDao accountDao public UserService(UserDao userDao, AccountDao accountDao) { this.userDao = userDao; this.accountDao = accountDao; }
public void test(){ System.out.println("UserService Test...");
userDao.test(); accountDao.test(); }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.xxxx.dao.UserDao" ></bean> <bean id="accountDao" class="com.xxxx.dao.AccountDao" ></bean> <bean id="userService" class="com.xxxx.service.UserService"> <constructor-arg name="userDao" ref="userDao"></constructor-arg> <constructor-arg name="accountDao" ref="accountDao"></constructor-arg> </bean>
</beans>
|
Bean对象和常用对象作为参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class UserService {
private UserDao userDao; private AccountDao accountDao; private String uname; public UserService(UserDao userDao, AccountDao accountDao, String uname) { this.userDao = userDao; this.accountDao = accountDao; this.uname = uname; }
public void test(){ System.out.println("UserService Test...");
userDao.test(); accountDao.test(); System.out.println("uname:" + uname); }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.xxxx.dao.UserDao" ></bean> <bean id="accountDao" class="com.xxxx.dao.AccountDao" ></bean> <bean id="userService" class="com.xxxx.service.UserService"> <constructor-arg name="userDao" ref="userDao"></constructor-arg> <constructor-arg name="accountDao" ref="accountDao"></constructor-arg> <constructor-arg name="uname" value="admin"></constructor-arg> </bean>
</beans>
|
循环依赖问题
Bean通过构造器注入,之间彼此相互依赖对方导致bean无法实例化
问题展示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class AccountService {
private RoleService roleService;
public AccountService(RoleService roleService) { this.roleService = roleService; }
public void test() { System.out.println("AccountService Test..."); } }
public class RoleService {
private AccountService accountService;
public RoleService(AccountService accountService) { this.accountService = accountService; }
public void test() { System.out.println("RoleService Test..."); } }
|
XML配置
1 2 3 4 5 6 7 8 9 10 11
|
<bean id="accountService" class="com.xxxx.service.AccountService"> <constructor-arg name="roleService" ref="roleService"/> </bean>
<bean id="roleService" class="com.xxxx.service.RoleService"> <constructor-arg name="accountService" ref="accountService"/> </bean>
|
如何解决:将构造器注入改为set方法注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class AccountService {
private RoleService roleService;
public void setRoleService(RoleService roleService) { this.roleService = roleService; }
public void test() { System.out.println("AccountService Test..."); } }
public class RoleService {
private AccountService accountService;
public void setAccountService(AccountService accountService) { this.accountService = accountService; }
public void test() { System.out.println("RoleService Test..."); } }
|
XML配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
<bean id="accountService" class="com.xxxx.service.AccountService"> <property name="roleService" ref="roleService"/> </bean>
<bean id="roleService" class="com.xxxx.service.RoleService"> <property name="accountService" ref="accountService"/> </bean>
|
@Resource注解
@Resource注解实现自动注入(反射)
默认根据属性字段名称查找对应的bean对象 (属性字段的名称与bean标签的id属性值相等)
如果属性字段名称未找到,则会通过类型(Class类型)查找
属性可以提供set方法,也可以不提供set方法
注解可以声明在属性级别 或 set方法级别
可以设置name属性,name属性值必须与bean标签的id属性值一致;如果设置了name属性值,就只会按照name属性值查找bean对象
当注入接口时,如果接口只有一个实现则正常实例化;如果接口存在多个实现,则需要使用name属性指定需要被实例化的bean对象
1.默认根据属性字段名称查找对应的bean对象 (属性字段的名称与bean标签的id属性值相等)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
public class UserService {
@Resource private UserDao userDao;
public void setUserDao(UserDao userDao) { this.userDao = userDao; }
public void test() { userDao.test(); } }
|
2.如果属性字段名称未找到,则会通过类型(Class类型)查找
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
public class UserService {
@Resource private UserDao ud;
public void setUd(UserDao ud) { this.ud = ud; }
public void test() { ud.test(); } }
|
3.属性可以提供set方法,也可以不提供set方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
public class UserService {
@Resource private UserDao userDao;
public void test() { userDao.test(); } }
|
4.注解可以声明在属性级别 或 set方法级别
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
public class UserService {
private UserDao userDao;
@Resource public void setUserDao(UserDao userDao) { this.userDao = userDao; }
public void test() { userDao.test(); } }
|
可以设置name属性,name属性值必须与bean标签的id属性值一致;如果设置了name属性值,就只会按照name属性值查找bean对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public class UserService {
@Resource(name = "userDao") private UserDao ud;
public void test() { ud.test(); } }
|
当注入接口时,如果接口只有一个实现则正常实例化;如果接口存在多个实现,则需要使用name属性指定需要被实例化的bean对象
定义接口类 IUserDao.java
1 2 3 4 5 6 7 8 9 10
|
public class UserDao02 implements IUserDao {
@Override public void test(){ System.out.println("UserDao02..."); } }
|
XML配置文件
1 2 3 4 5 6 7
| <context:annotation-config/>
<bean id="userService" class="com.xxxx.service.UserService"></bean>
<bean id="userDao01" class="com.xxxx.dao.UserDao01"></bean> <bean id="userDao02" class="com.xxxx.dao.UserDao01"></bean>
|
使用注解 UserService.java
1 2 3 4 5 6 7 8 9 10 11 12 13
|
public class UserService {
@Resource(name = "userDao01") private IUserDao iUserDao;
public void test() { iUserDao.test(); } }
|
@Autowired注解
@Autowired注解实现自动化注入:
默认通过类型(Class类型)查找bean对象 与属性字段的名称无关
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
public class UserService {
@Autowired private UserDao userDao;
public void setUserDao(UserDao userDao) { this.userDao = userDao; }
public void test() { userDao.test(); } }
|
属性可以提供set方法,也可以不提供set方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
public class UserService {
@Autowired private UserDao userDao;
public void test() { userDao.test(); } }
|
注解可以声明在属性级别 或 set方法级别
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
public class UserService {
private UserDao userDao;
@Autowired public void setUserDao(UserDao userDao) { this.userDao = userDao; }
public void test() { userDao.test(); } }
|
可以添加@Qualifier结合使用,通过value属性值查找bean对象(value属性值必须要设置,且值要与bean标签的id属性值对应)
/**
* @Autowired注解实现自动化注入
* 可以添加@Qualifier结合使用,通过value属性值查找bean对象
value属性值必须要设置,且值要与bean标签的id属性值对应
*/
public class UserService {
@Autowired
@Qualifier(value="userDao") // value属性值必须要设置,且值要与bean标签的id属性值对应
private UserDao userDao;
public void test() {
userDao.test();
}
}
推荐使用@Resource 注解是属于J2EE的,减少了与Spring的耦合