依赖注入(Dependency Injection,DI)。
依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 .
注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配 .
说白了, 有些Bean对象的创建是有所依赖的, 比如说, 业务层的对象就依赖于持久层的对象.
一. 将持久层的bean实例注入到业务层
主要就是两种方法
一种就是通过构造器实现, 一种就是通过set方法来实现
其实重点是set方法来注入
(1). set方法注入依赖资源
要求被注入的属性 , 必须有set方法 , set方法的方法名由set + 属性首字母大写
也就是说set方法的命名有规范
在bean标签体中使用一个财产标签
property
这个财产标签的属性有三个
name:
ref:
value:
先写接口和实现类
public interface UserService {
public void save();
}
public class UserServiceImpl implements UserService {
/*
* 依赖的资源*/
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
/*如果没有注入持久层的对象, 那么在这里我们还得自己获取*/
//ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
//UserDao UserDao = (UserDao) app.getBean("userDao");
userDao.getUser();
System.out.println("调用了持久层的方法");
}
}
在去spring的配置文件中配置业务层的bean
<!--这里配置业务层的bean, 并为业务层注入依赖资源-->
<bean id="userService" class="service.serviceimpl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
测试
public class UserServiceTest {
@Test
public void testUserService(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) app.getBean("userService");
userService.save();
}
}
这是Mysql的实现方法
调用了持久层的方法
(2). 构造器方法注入依赖资源
要求有该属性的构造器
注意没有使用工厂类的话, 补回无参的构造器
这里是在bean的标签体中使用构造器标签
constructor-arg
属性有五个
name
ref
index
value
type
public class UserServiceImpl implements UserService {
/*
* 依赖的资源*/
private UserDao userDao;
/*public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}*/
//使用构造器方法注入
public UserServiceImpl(UserDao userDao){
this.userDao = userDao;
}
//注意, 如果没有使用工厂类, 这里别忘记补回无参的构造器
public UserServiceImpl(){}
@Override
public void save() {
/*如果没有注入持久层的对象, 那么在这里我们还得自己获取*/
//ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
//UserDao UserDao = (UserDao) app.getBean("userDao");
userDao.getUser();
System.out.println("调用了持久层的方法");
}
}
<!--这里配置业务层的bean, 并为业务层注入依赖资源-->
<!--<bean id="userService" class="service.serviceimpl.UserServiceImpl">
<property name="userDao" ref="userDao" ></property>
</bean>-->
<bean id="userService" class="service.serviceimpl.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao" ></constructor-arg>
</bean>
小结: 说白了, 注入的意思就是, 将依赖的资源作为属性放在类中, 并为之写好set或者构造器方法. 然后经过配置, 在创建该Bean实例时, 顺带着去执行该bean的set或者构造方法. 这样就自动为该类注入了依赖的资源. 完美!!!
二. 明显的是, 依赖的资源其实不止可以是bean实例, 还有其实东西也会成为依赖的资源
普通数据类型和集合等也可以在容器中进行注入
(1). 普通数据类型
public class User {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}`在这里插入代码片`
public int getAge() {
return age;
}
}
<!--普通数据类型的注入-->
<bean id="user" class="model.User">
<property name="age" value="18"></property>
<property name="name" value="张三"></property>
</bean>
public class UserTest {
@Test
public void testUser(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) app.getBean("user");
System.out.println(user.getAge());
System.out.println(user.getName());
}
}
18
张三
小结: 明显可以看出, ref属性的值就是配置文件中已经配置好的bean对象的id, value属性值就是普通数据类型
(2). 集合类型
(1) List
(2)Map
(3)properties
public class UserDaoMysqlImpl implements UserDao {
/*依赖的集合资源*/
private List<String> stringList;
private List<User> userList;
private Map<String, User> userMap;
private Properties properties;
//资源的set方法
public void setStringList(List<String> stringList) {
this.stringList = stringList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
public void setUserMap(Map<String, User> userMap) {
this.userMap = userMap;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public void getUser() {
System.out.println("这是Mysql的实现方法");
}
public void show(){
System.out.println(stringList);
System.out.println(userList);
System.out.println(userMap);
System.out.println(properties);
}
}
<!--普通数据类型的注入-->
<bean id="user1" class="model.User">
<property name="age" value="18"></property>
<property name="name" value="张三"></property>
</bean>
<bean id="user2" class="model.User">
<property name="age" value="19"></property>
<property name="name" value="李四"></property>
</bean>
<!--集合类型的注入-->
<bean id="userDao" class="dao.daoimpl.UserDaoMysqlImpl">
<property name="stringList">
<list>
<value>李白</value>
<value>宫本</value>
<value>孙尚香</value>
</list>
</property>
<property name="userList">
<list>
<ref bean="user1"></ref>
<ref bean="user2"></ref>
</list>
</property>
<property name="userMap">
<map>
<entry key="王者" value-ref="user1"></entry>
<entry key="青铜" value-ref="user2"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="aaa">bbb</prop>
<prop key="ccc">ddd</prop>
<prop key="kkk">ggg</prop>
<prop key="mmm">nnn</prop>
</props>
</property>
</bean>
public class UserDaoTest {
@Test
public void testUserDao(){
/*
* 获取UserDao接口的实现类并测试方法
* 使用loc容器来获取*/
//1.加载spring的配置文件来创建一个叫app的对象
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) app.getBean("userDao");
userDao.show();
}
}
[李白, 宫本, 孙尚香]
[User{name='张三', age=18}, User{name='李四', age=19}]
{王者=User{name='张三', age=18}, 青铜=User{name='李四', age=19}}
{aaa=bbb, ccc=ddd, kkk=ggg, mmm=nnn}