依赖注入的两种方式:
网上说的三种注入方式中的接口注入在官方的文档中已经没有了(spring4.3),所以现在的依赖注入的方式有两种。
- 构造方法注入: 通过调用带参数的构造方法来实现,每一个参数都代表是一个依赖。调用(注入)的对象通过在被注入对象中的构造方法中声明的参数列表让容器知道他要依赖哪些对象,然后spring容器检查被注入对象的构造方法,需要哪些对象,接着进行注入。
新建service包,新建UserService接口定义服务方法:
package com.demo.service;
/** * Created with IDEA * * @author DuzhenTong * @Date 2018/3/26 * @Time 19:20 */
public interface UserService {
public void login();
}
新建dao包,新建UserDao类
package com.demo.dao;
/** * Created with IDEA * * @author DuzhenTong * @Date 2018/3/26 * @Time 19:18 */
public class UserDao {
public void login() {
System.out.println("用户登录!!!");
}
}
新建impl包,新建UserService的实现类UserServiceImpl
package com.demo.impl;
import com.demo.dao.UserDao;
import com.demo.service.UserService;
/** * Created with IDEA * * @author DuzhenTong * @Date 2018/3/26 * @Time 19:21 */
public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserServiceImpl(UserDao userDao) {
this.usrDao = userDao;
}
@Override
public void login() {
userDao.login();
}
}
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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean id="UserServiceImpl" class="com.demo.impl.UserServiceImpl">
<constructor-arg>
<ref bean="userDao" />
</constructor-arg>
</bean>
<bean id="userDao" class="com.demo.dao.UserDao" />
</beans>
新建测试类:
package com.demo.test;
import com.demo.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/** * Created with IDEA * * @author DuzhenTong * @Date 2018/3/26 * @Time 19:33 */
public class Test {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) app.getBean("UserServiceImpl");
userService.login();
}
}
运行测试类Test,输出:用户登录!!!
- setter注入:当前对象只需要为依赖对象所对应的属性添加相应的setter方法,spring容器通过setter方法将对应的依赖对象设置到被注入对象。
修改UserServiceImpl类:加上对应的set方法
package com.demo.impl;
import com.demo.dao.UserDao;
import com.demo.service.UserService;
/** * Created with IDEA * * @author DuzhenTong * @Date 2018/3/26 * @Time 19:21 */
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void login() {
userDao.login();
}
}
注释掉spring配置文件中之前的bean标签,加上
<bean id="UserServiceImpl" class="com.demo.impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
<bean id="userDao" class="com.demo.dao.UserDao"/>
其他不变,运行Test类,得到和之前一样的输出结果
我们看到上面的所有代码都没有使用new创建实例,其实spring的ioc容器已经帮我们创建好了。
什么时候建议选择构造注入?什么时候建议选择setter注入?
使用强依赖的时候选择构造注入,因为构造注入每次都是初始化好了之后才返回给调用的代码。
setter注入主要应用于可选的依赖关系,通常要在相关类的内部关联合理的默认值。否则在使用相关依赖的地方一定要执行非空检查。Setter注入的一个好处是后续可以使用setter方法来重新配置或注入相关依赖。 注意,可以使用 setter方法上的@Required注释来使该属性成为必需的依赖项。