依赖注入的概念
Spring中的依赖注入,称为dependency Injection,Ioc的作用降低程序之间的耦合,依赖关系管理交给Spring来维护,在当前类中需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明,依赖关系的维护,我们称之为依赖注入
依赖注入的三种数据
基本数据类型和String、其他bean类型(在配置文件中或者注解配置过的bean)、复杂类型/集合类型
依赖注入的三种方式
①使用构造函数 ②使用set方法提供 ③使用复杂类型注入/集合类型注入
构造函数注入
①目录结构,接口实现类中属性和方法
public class AccountServiceImpl implements IAccountService {
//如果是经常变化的数据,并不适用于注册的方式
private String name;
private Integer age;
private Date brithday;
AccountServiceImpl(String name,Integer age,Date brithday){
this.name=name;
this.age=age;
this.brithday=brithday;
}
public void saveAccount(){
System.out.println("service中的saveAccount方法执行了...."+name+age+brithday);
}
}
②修改配置文件
在配置文件中,用使用标签constructor-arg, 标签出现的位置bean标签内部
标签中属性 type:用于指定要注入的数据的数据类型,该数据也是构造函数中某个或者某些参数的类型,不能独立实现注入,index:用于指定注入的数据给构造函数中指定索引位置的参数赋值,索引的位置从0开始,需要记索引,name:用于给指定后遭函数中指定名称的参数赋值(常用的)
=======================以上三个用于给构造函数中参数赋值=========================
value:用于给基本类型和Strig提供数据,ref:就是引用指定其他的bean数据,它指的就是在Spring Ioc核心容器出现过的bean对象如下
<bean id="accountService" class="com.ithema.jdbc.service.impl.AccountServiceImpl">
<constructor-arg name="name" value="name"></constructor-arg>
<constructor-arg name="age" value="20"></constructor-arg>
<constructor-arg name="brithday" ref="now"></constructor-arg>
</bean>
<!--配置一个日期对象-->
<bean id="now" class="java.util.Date"></bean>
③测试实现类,运行代码得到以下结果,成功实现了依赖注入
package com.ithema.jdbc.ui;
import org.springframework.core.io.ClassPathResource;
import javax.annotation.Resource;
public class Client {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("ApplicationContext.xml");
IAccountService as= (IAccountService) ac.getBean("accountService");
System.out.println(as);
as.saveAccount();
}
优势:在获取bean对象时候注入数据是必须的操作,否则对象无法创建成功 弊端:改变了bean对象的实例化方式,使我们在创建对象时候用不到这些数据也必须提供
set方式注入(是我们经常用的注入方式)
①在接口类中实现属性的set的方法
package com.ithema.jdbc.service.impl;
import com.ithema.jdbc.service.IAccountService;
import java.util.Date;
/**
* 账户的业务层实现类
*/
public class AccountServiceImpl2 implements IAccountService {
//如果是经常变化的数据,并不适用于注册的方式
private String name;
private Integer age;
private Date brithday;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setBrithday(Date brithday) {
this.brithday = brithday;
}
public void saveAccount(){
System.out.println("service中的saveAccount方法执行了...."+"名字:"+name+"年纪:"+age+"生日:"+brithday);
}
}
②配置文件中修改代码
<bean id="accountService2" class="com.ithema.jdbc.service.impl.AccountServiceImpl2">
<property name="name" value="Test"></property>
<property name="age" value="21"></property>
<property name="brithday" ref="now"></property>
</bean>
③测试类的运行,得到以下结果
package com.ithema.jdbc.ui;
import org.springframework.core.io.ClassPathResource;
import javax.annotation.Resource;
public class Client {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("ApplicationContext.xml");
IAccountService as= (IAccountService) ac.getBean("accountService2");
System.out.println(as);
as.saveAccount();
}
使用set方法实现注入
优势:创建对象没有明确的限制,可以直接使用默认的构造函数 劣势:如果某个成员必须有值,则获取对象时候,set无法执行
复杂类型方式的注入
①接口实现类set方法
package com.ithema.jdbc.service.impl;
import com.ithema.jdbc.service.IAccountService;
import java.lang.reflect.Array;
import java.util.*;
/**
* 账户的业务层实现类
*/
public class AccountServiceImpl3 implements IAccountService {
//复杂类型注入/集合注入
private String[] myStrs;
private List<String> myList;
private Map<String,String>myMap;
private Properties myPro;
public void setMyStrs(String[] myStrs) {
this.myStrs = myStrs;
}
public void setMyList(List<String> myList) {
this.myList = myList;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
public void setMyPro(Properties myPro) {
this.myPro = myPro;
}
public void saveAccount(){
System.out.println(Arrays.toString(myStrs));
System.out.println(myList);
System.out.println(myMap);
System.out.println(myPro);
}
}
②改变配置文件中的代码
<bean id="accountService3" class="com.ithema.jdbc.service.impl.AccountServiceImpl3">
<property name="myStrs">
<array>
<value>AAAA</value>
<value>BBBB</value>
<value>CCC</value>
</array>
</property>
<property name="myList">
<list>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</list>
</property>
<property name="myMap">
<map>
<entry key="test1" value="AA"></entry>
<entry key="test2" value="BB"></entry>
<entry key="test3" value="CC"></entry>
</map>
</property>
<property name="myPro">
<props>
<prop key="test2">A</prop>
<prop key="test1">B</prop>
<prop key="test">C</prop>
</props>
</property>
</bean>
③测试类的执行,执行的结果如下
package com.ithema.jdbc.ui;
import org.springframework.core.io.ClassPathResource;
import javax.annotation.Resource;
public class Client {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("ApplicationContext.xml");
IAccountService as= (IAccountService) ac.getBean("accountService3");
System.out.println(as);
as.saveAccount();
}