- DI - 依赖注入
所谓依赖注入是一个控制反转的设置过程,要知道依赖注入必须要知道IOC(控制反转)
是什么。
所谓的IOC称之为控制反转,简单来说就是将对象的创建的权力和生命周期的管理过程交
付给Spring框架来处理,从此在开发过程中不再需要关注对象的创建和生命周期的管理,而在需
要的时候由Spring框架提供,这个由Spring框架管理对象创建和生命周期的机制称之为控制反转
而在创建对象的过程中Spring依据配置对 对象进行属性设置,那么这个过程称之为依赖注入,即DI。
2.Spring注入方式
**构造方法的注入**
在对象创建的过程中通过构造方法传入并设置对象的属性,Spring也可以通过这样的构造方法实现属性的注入
public class User01{
private String name;
private int id;
private Dog dog;
public User01(String name,int id,Dog dog){
this.name=name;
this.id=id;
this.dog=dog;
}
@Override
public String tostring(){
return "User01{"+"name="+name+","+"id="+id+","+"dog="+dog+"}";
}
}
User01类中有一个变量是name,那么希望通过构造方法注入值,User01中提供了相应的构造方法,然后再
Spring的配置文件中做如下配置
< !--
index:为构造方法的第几个参数进行配置
name:为构造方法的哪个名字的参数进行配置
**index和name可以配置任何一个 或者同时配置 但是要求一旦配置就要必须正确
**推荐优先使用index方法配置 防止没有源码造成name无法匹配到正确参数
type:该构造方法的参数的值
value:该构造方法参数的值,用来指定基本值
ref:该构造方法参数的值,用来指定引用其他bean的值
--!>
<bean id="user01" class="cn.com.User01">
<constructor-arg name="name" type="java.lang.String" value="丽萨">
<constructor-arg index="1" name="id" value="22">
<constructor-arg name="dog" ref="dog" >
</bean>
<bean id="dog" class="cn.com.Dog"></bean>
该测试类为:
@Text
public void test(){
ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml");
User01 user=(User01)context.getBean("user01");
System.out.println(user);
}
set方法注入
通常的javabean属性都会私有化,而对外暴露setxxx()方法和getxxx()方法,此时Spring可以通过
这样的setxxx()方法将属性值注入对象
假设有一个student类
private String name;
private int age;
public Student (String name,int age){
this.name=name;
this.age=age;
}
@Override
public String toString(){
return "Student{"+"name"+name+","+"age"+age+"}";
}
}
Spring配置文件中配置为
<bean id="student" class="cn.com.Student">
<property name="name" value="丽萨">
<property name="age" value="22"/>
</bean>
测试代码为
@Test
public void test02(){
ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml");
Student student=(Student)context.getBean("student");
System.out.println(student);
}
非Spring内置的参数可以直接注入类型
即对象的注入,利用ref属性配置进行bean的引用,举例一个常用的场景,我们再Service层进行业务逻辑操作,在
DAO层进行数据库的操作,在Service层需要一个DAO实例,如下 我们有一个DAO类
public class UserDao{
public void getDate(){
System.out.println("获取到了数据库的数据.....");
}
}
还有一个UserService
public class UserService{
private UserDao userDao;
public UserService(UserDao userDao){
this.userDao=userDao;
}
public void getDao(){
userDao.getData();
}
}
那么Spring的配置为
<bean id ="userService" class="cn.com.UserService">
<property name="userDao" ref="userDao"/>
</bean>
<bean id="userDao" class="cn.com.UserDao"/>
即需要配置两个bean,第一个bean用来配置UserService的实例,第二个bean用来配置UserDao的实例,在获取UserService
实例的时候将第二个bean获取的userDao作为参数传入。也可以通过构造方法进行对象的传入,这里不再进行演示
此测试代码也不再做演示
自动装配
在Spring的set方法实现的注入过程中,支持自动装配,所谓自动装配机制,会根据要设置的javaBean属性的名字或者类型 到Spring中自动寻找对应的id或者类型的进行设置,从而省去一次装配的过程,简化了配置
配置自动装配分为 指定的开启自动装配 和 为全局配置自动装配
要配置属性autowire
为指定的bean开启自动装配需
<bean id="student" class="cn.com.Student" autowire="byName"/>
autowire设定自动装配:
byName:根据javabean中需要注入的属性的名字 ,在spring容器中找对应id的将该
的对象复制给 当前的属性
byType:根据javabean中需要注入的属性的类型,在spring容器中找对应class类型的将该
的对象复制给 当前的属性
**byType方式 根据类型进行匹配,可能匹配到多个,此时会抛出异常。而byName是通过id来
寻找,id没有重复,不会有这方面的问题,所以推荐使用byName方式
为全局开启自动装配
属性配置到beans标签中,同指定配置一样有byName与byType两种
<?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-3.2.xsd"
default-autowire="byName">
以上,是对Spring DI理解,是学习笔记,如果有错误之处,请留言指出,谢谢!