本篇主要介绍Spring框架的DI(依赖注入)机制。事实上,在上一篇的Spring基础学习(三)中所讲的bean的三种实例方式中的实例工厂模式也用到了依赖注入方式。之所以先写bean的实例方式再写依赖是因为我认为这个较为简单,先实际操作后再去理解这个概念可能会有事半功倍的效果。编程嘛,实操是可以很大程度上帮组理解的。
l DI Dependency Injection ,依赖注入
class B {
private A a; //B类依赖A类
}
依赖:一个对象需要使用另一个对象
注入:通过setter方法进行另一个对象实例设置。
l 例如:
classBookServiceImpl{
//之前开发:接口 = 实现类 (service和dao耦合)
//privateBookDao bookDao = new BookDaoImpl();
//spring之后 (解耦:service实现类使用dao接口,不知道具体的实现类)
privateBookDao bookDao;
setter方法
}
模拟spring执行过程
创建service实例:BookService bookService = newBookServiceImpl() -->IoC <bean>
创建dao实例:BookDao bookDao = new BookDaoImple() -->IoC
将dao设置给service:bookService.setBookDao(bookDao); -->DI <property>
例:接口类
public interface BookDao {
public void addBook();
}
实现类
public class BookDaoImpl implements BookDao {
@Override
public void addBook() {
System.out.println("di add book");
}
}
Service类
public interface BookService {
public abstract void addBook();
}
public class BookServiceImpl implements BookService {
// 方式1:之前,接口=实现类
// private BookDao bookDao = new BookDaoImpl();
// 方式2:接口 + setter
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void addBook(){
this.bookDao.addBook();
}
配置文件
<!-- 创建service -->
<bean id="bookServiceId" class="com.itheima.b_di.BookServiceImpl">
<property name="bookDao" ref="bookDaoId"></property>
</bean>
<!-- 创建dao实例 -->
<bean id="bookDaoId" class="com.itheima.b_di.BookDaoImpl"></bean>
测试:
@Test
public void demo01(){
//从spring容器获得
String xmlPath = "com/itheima/b_di/beans.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
BookService bookService = (BookService) applicationContext.getBean("bookServiceId");
bookService.addBook();
}
属性依赖注入:
属性依赖注入分为手动注入和自动装配,一般进行配置信息都采用手动,自动装配容易产生很难发现的错误。手动装配又分为俩种,一种是基于xml装配,一种是基于注解装配。下面将对手动装配的两种方式进行例题说明.
基于XML的构造方法注入:
<constructor-arg>用于配置构造方法的参数
name为参数的名称,value用于设置普通参数,ref引用数据,一般是另一个bean id或name值,index为参数的索引,从0开始。type为参数类型
例:目标类
public class User {
private Integer uid;
private String username;
private Integer age;
public User(Integer uid, String username) {
super();
this.uid = uid;
this.username = username;
}
public User(String username, Integer age) {
super();
this.username = username;
this.age = age;
}
}
配置文件:
<bean id="userId" class="com.itheima.f_xml.a_constructor.User" >
<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>
<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
</bean>
基于XML的setting方法注入:
普通数据:<property name = "" value = ""></property>等效于<property name = "">value</property>
引用数据:<property name = "" ref = ""></property>等效于<property name = ""><ref></ref></property>
例如:
<bean id="personId" class="com.itheima.f_xml.b_setter.Person">
<property name="pname" value="阳志"></property>
<property name="age">
<value>1234</value>
</property>
<property name="homeAddr" ref="homeAddrId"></property>
<property name="companyAddr">
<ref bean="companyAddrId"/>
</property>
</bean>
<bean id="homeAddrId" class="com.itheima.f_xml.b_setter.Address">
<property name="addr" value="阜南"></property>
<property name="tel" value="911"></property>
</bean>
<bean id="companyAddrId" class="com.itheima.f_xml.b_setter.Address">
<property name="addr" value="北京八宝山"></property>
<property name="tel" value="120"></property>
</bean>
集合注入:
集合的注入都是给<property>添加子标签,<array>、<list>、<set>、<map>、<props>等
例如:
<bean id="collDataId" class="com.itheima.f_xml.e_coll.CollData" >
<property name="arrayData">
<array>
<value>DS</value>
<value>DZD</value>
<value>屌丝</value>
<value>屌中屌</value>
</array>
</property>
<property name="listData">
<list>
<value>于嵩楠</value>
<value>曾卫</value>
<value>杨煜</value>
<value>曾小贤</value>
</list>
</property>
<property name="setData">
<set>
<value>停封</value>
<value>薄纸</value>
<value>关系</value>
</set>
</property>
<property name="mapData">
<map>
<entry key="jack" value="杰克"></entry>
<entry>
<key><value>rose</value></key>
<value>肉丝</value>
</entry>
</map>
</property>
<property name="propsData">
<props>
<prop key="高富帅">嫐</prop>
<prop key="白富美">嬲</prop>
<prop key="男屌丝">挊</prop>
</props>
</property>
</bean>
注解依赖注入:(只做介绍,不做案例)
1. @Component取代<bean class="">
@Component("id")取代 <beanid="" class="">
2.web开发,提供3个@Component注解衍生注解(功能一样)取代<beanclass="">
@Repository:dao层
@Service:service层
@Controller:web层