所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。

使用构造器注入

 
1
2
3
4
<constructor-arg index=“0” type=“java.lang.String” value=“xxx”/>//构造器注入
 
<bean id="xxx" class="daoimpl.PersonDaoImpl"></bean>
<constructor-arg index=“0” type=“java.lang.String” ref=“xxx”/>//构造器注入

PS:其中index的值代表构造器的第几个参数,type代表属性类型,value的值的类型为基本类型,ref的值为引用bean的名字。

范例:

配置文件:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
<?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-2.5.xsd">
 
           <bean id="persondaoimpl" class="daoimpl.PersonDaoImpl"></bean>
           <bean id="personService" class="zmc.PersonServicebean" >
               <constructor-arg index="0" type="java.lang.String" value="zmcheng"></constructor-arg>
               <constructor-arg index="1" type="dao.PersonDao" ref="persondaoimpl"></constructor-arg>
           </bean>
 
</beans>

依赖对象类:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package zmc;
import dao.PersonDao;
import zmcjk.PersonService;
 
public class PersonServicebean implements PersonService {
 
  private String name;
  private PersonDao personDao ;
  public PersonServicebean(String name, PersonDao personDao) {
      super();
      this.name = name;
      this.personDao = personDao;
}
 
  public String getName() {
    return name;
}
 
 
  public void setName(String name) {
   this.name = name;
}
 
 
public PersonDao getPersonDao() {
   return personDao;
}
 
 
public void setPersonDao(PersonDao personDao) {
    this.personDao = personDao;
}
 
 
public void save(){
   System.out.println(this.name);
   personDao.add();
}
}

使用属性setter方法注入

基本类型对象注入:

 
1
2
3
<bean id="orderService" class="cn.itcast.service.OrderServiceBean">
    <property name=“name” value=“zhao”/>
</bean>

示例:

配置文件:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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-2.5.xsd">
 
           <bean id="persondaoimpl" class="daoimpl.PersonDaoImpl"></bean>
           <bean id="personService" class="zmc.PersonServicebean" >
               <property name="name" value="zmc"></property>
               <property name="age" value="88"></property>
               <property name="persondao" ref="persondaoimpl"></property>
           </bean>
 
</beans>

bean类:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package zmc;
 
import dao.PersonDao;
import zmcjk.PersonService;
 
public class PersonServicebean implements PersonService {
 
private PersonDao persondao  = null;
private String name=null;
private Integer age;
public Integer getAge() {
return age;
}
 
public void setAge(Integer age) {
this.age = age;
}
 
public String getName() {
return name;
}
 
public void setName(String name) {
this.name = name;
}
 
public PersonDao getPersondao() {
return persondao;
}
 
public void setPersondao(PersonDao persondao) {
this.persondao = persondao;
}
 
public void save(){
System.out.println(this.name);
System.out.println(this.age);
persondao.add();
}
}

注入其他bean:

方式一

 
1
2
3
4
<bean id="orderDao" class="cn.itcast.service.OrderDaoBean"/>
<bean id="orderService" class="cn.itcast.service.OrderServiceBean">
<property name="orderDao" ref="orderDao"/>
</bean>

PS:其中name为属性名称,ref是要注入bean的名称

示例:

DAO层:

 
1
2
3
4
5
6
7
8
9
10
11
12
package dao;
public interface PersonDao {
void add();
}
 
package daoimpl;
import dao.PersonDao;
public class PersonDaoImpl implements PersonDao {
public void add(){
     System.out.println("执行dao的方法");
    }
}

业务层:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package zmc;
 
import dao.PersonDao;
import zmcjk.PersonService;
public class PersonServicebean implements PersonService {
private PersonDao persondao  = null;
public PersonDao getPersondao() {
return persondao;
}
 
public void setPersondao(PersonDao persondao) {
this.persondao = persondao;
}
 
public void save(){
persondao.add();
}
 
}

测试:

 
1
2
3
4
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService ps = (PersonService)ctx.getBean("personService");
ps.save();
ctx.close();

配置文件:

 
1
2
3
4
5
6
7
8
9
10
11
12
<?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-2.5.xsd">
 
           <bean id="persondaoimpl" class="daoimpl.PersonDaoImpl"></bean>
           <bean id="personService" class="zmc.PersonServicebean" >
              <property name="persondao" ref="persondaoimpl"></property>
           </bean>
 
</beans>

测试结果:执行dao的方法

方式二(使用内部bean,但该bean不能被其他bean使用,不推荐)

 
1
2
3
4
5
<bean id="orderService" class="cn.itcast.service.OrderServiceBean">
<property name="orderDao">
<bean class="cn.itcast.service.OrderDaoBean"/>
</property>
</bean>

集合类型的装配:

Spring可以对集合类型进行注入包括:Set集合,properties属性集合,Map集合以及List集合。

注入方式如下:

配置文件:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<bean id="order" class="cn.itcast.service.OrderServiceBean">
    <property name="lists">
          <list>
              <value>lihuoming</value>
               <value>zmcheng</value>
         </list>
      </property>
      <property name="sets">
         <set>
            <value>set1</value>
             <value>set2</value>
        </set>
      </property>
      <property name="maps">
        <map>
            <entry key="lihuoming" value="28"/>
            <entry key="zmcheng" value="22"/>
       </map>
     </property>
     <property name="properties">
        <props>
             <prop key="12">sss</prop>
             <prop key="13">saa</prop>
       </props>
      </property>
</bean>

编码模拟Spring使用属性setter方法注入的原理:

简单模拟的Spring容器:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package zmcSpring;
 
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
/*
 * 简单模拟Spring容器
 */
public class ZmcClassPathXMLApplicationContext {
 
private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();//保存bean的信息
private Map<String,Object> sigletons = new HashMap<String,Object>();//引用所有bean对象
 
public ZmcClassPathXMLApplicationContext(String fileName){
this.readXML(fileName);
this.instanceBeans();
this.injectObject();//依赖注入
}
 
/*
 * 为bean属性注入值
 */
private void injectObject() {
   for(BeanDefinition beanDefinition : beanDefines){
       Object bean = sigletons.get(beanDefinition.getId());//此时bean还没有注入
       //下面开始进行依赖注入
       if(bean!=null){
         //取得bean的属性描述
       try {
        PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();//bean的属性
        for(PropertyDefinition propertyDefinition : beanDefinition.getProperty()){//用户配置文件中定义的属性
         for(PropertyDescriptor properdesc : ps){
       //判断配置文件中属性的名称和bean中属性的名称是否相同
        if(propertyDefinition.getName().equals(properdesc.getName())){
               Method setter = properdesc.getWriteMethod();//获得属性的setter方法
               if(setter!=null){
               Object value = sigletons.get(propertyDefinition.getRef());
               try {
                  setter.invoke(bean, value);
                } catch (Exception e) {
                   e.printStackTrace();
              } //把引用对象注入到属性
}}}}}
catch(Exception e){
....
}
/*
 * 完成bean的实例化
 */
private void instanceBeans(){
for(BeanDefinition beanDefinition : beanDefines){
try {
sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
 * 读取XMl配置文件
 * @param filename
 */
public void readXML(String fileName){
SAXReader saxReader = new SAXReader();
Document document = null;
try{
URL xmlpath = this.getClass().getClassLoader().getResource(fileName);
document = saxReader.read(xmlpath);
Map<String,String> nsMap = new HashMap<String,String>();
nsMap.put("ns", "http://www.springframework.org/schema/beans");//加入命名空间
XPath xsub = document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径
    xsub.setNamespaceURIs(nsMap);//设置命名空间
    List<Element> beans = xsub.selectNodes(document);
    for(Element element : beans){
       String id = element.attributeValue("id");
       String clazz = element.attributeValue("class");
       BeanDefinition beanDefinition = new BeanDefinition(id,clazz);
      XPath propertysub =  element.createXPath("ns:property");//nodename(节点名称):表示选择该节点的所有子节点
     propertysub.setNamespaceURIs(nsMap);
     List<Element> propertys = propertysub.selectNodes(element);
     for(Element property:propertys){
     String propertyName = property.attributeValue("name");
     String propertyRef = property.attributeValue("ref");
     PropertyDefinition pd = new PropertyDefinition(propertyName, propertyRef);
     beanDefinition.getProperty().add(pd);
     }
      beanDefines.add(beanDefinition);
    }
}
catch (Exception e){
e.printStackTrace();
}
}
/*
 *获取bean实例
 */
public Object getBean(String beanName){
return this.sigletons.get(beanName);
}
}

Bean属性信息:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package zmcSpring;
 
import java.util.ArrayList;
import java.util.List;
public class BeanDefinition {
private String id;
private String className;
private List<PropertyDefinition> property = new ArrayList<PropertyDefinition>();
public List<PropertyDefinition> getProperty() {
return property;
}
public void setProperty(List<PropertyDefinition> property) {
this.property = property;
}
 
public BeanDefinition() {
  super();
}
 
public BeanDefinition(String id, String className) {
super();
this.id = id;
this.className = className;
}
 
public String getId() {
return id;
}
 
public void setId(String id) {
this.id = id;
}
 
public String getClassName() {
return className;
}
 
public void setClassName(String className) {
this.className = className;
}
}

Property信息:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package zmcSpring;
public class PropertyDefinition {
 public PropertyDefinition(String name, String ref) {
super();
this.name = name;
this.ref = ref;
}
 
public String getName() {
return name;
}
 
public void setName(String name) {
this.name = name;
}
 
public String getRef() {
return ref;
}
 
public void setRef(String ref) {
this.ref = ref;
}
 
private String name;
 private String ref;
}

测试类:

 
 
 
 
 

Java

 
1
2
3
4
5
6
7
8
 
@Test
public void T() {
 
ZmcClassPathXMLApplicationContext zmc = new ZmcClassPathXMLApplicationContext("beans.xml");
PersonService ps = (PersonService)zmc.getBean("personService");
ps.save();
 
}

Spring第六弹—-依赖注入之使用构造器注入与使用属性setter方法注入的更多相关文章

  1. spring 构造方法注入和setter方法注入的XML表达

    1.构造方法注入 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC ...

  2. 哪种依赖注入方式你建议使用,构造器注入,还是 Setter方法注入?

    你两种依赖方式都可以使用,构造器注入和Setter方法注入.最好的解决方案是用构造器参数实现强制依赖,setter方法实现可选依赖.

  3. spring setter方法注入

    <bean id="dao" class="Dao"></bean> <bean id="service" c ...

  4. SpringBoot 构造器注入、Setter方法注入和Field注入对比

    0. 引入 今天在看项目代码的时候发现在依赖注入的时候使用了构造器注入,之前使用过 Field 注入和 Setter 方法注入,对构造器注入不是很了解.经过查阅资料看到,Spring 推荐使用构造器注 ...

  5. .NET手记-Autofac进阶(属性和方法注入 Property and Method Injection)

    尽管构造函数参数注入是传递参数值给当前构造的组件的优先方式,但是你也可以使用属性或者方法注入来提供参数值. 属性注入使用可写入的变量而不是构造函数参数来完成注入.方法注入则通过方法来设置依赖项. 属性 ...

  6. Autofac官方文档翻译--一、注册组件--3属性和方法注入

    官方文档:http://docs.autofac.org/en/latest/register/prop-method-injection.html Autofac 属性和方法注入 虽然构造函数参数注 ...

  7. Spring第七弹—依赖注入之注解方式注入及编码解析@Resource原理

        注入依赖对象可以采用手工装配或自动装配,在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果. 手工装配依赖对象  手工装配依赖对象,在这种方式中又有两种编 ...

  8. spring构造函数注入、setter方法注入和接口注入

    Spring开发指南中所说的三种注入方式: Type1 接口注入 我们常常借助接口来将调用者与实现者分离.如: public class ClassA { private InterfaceB clz ...

  9. spring 3.1.13中新增的util @value注解,给类或方法注入值

    在spring 3.0以上版本中,可以通过使用@value,对一些如xxx.properties文件 ,进行键值对的注入,例子如下: 一.类变量注入 1 首先在applicationContext.x ...

随机推荐

  1. 如何让jquery-easyui的combobox像select那样不可编辑

    http://zhidao.baidu.com/link?url=td61iIn_MBCs1FvT7b-B9Lp9VzlyrcnGmSbkCy1EsSzuod5o47zTmJFRQ-xizxdqv1E ...

  2. 008杰信-创建购销合同Excel报表系列-1-建四张表

    本博客的内容来自于传智播客: 我们现在开始要做表格了,根据公司要求的表格的形式,来设计数据库.规划针对这个表格要设计几张表,每张表需要哪些字段. 根据公司原有的表格,设计数据库: 原有的表格

  3. hdu 1513(dp+滚动数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 思路:n这么大,可以采用滚动数组,然后就是求原串和反串的LCS了. #include<io ...

  4. 剑指 offer set 14 打印 1 到 N 中 1 的个数

    总结 1. 假设 n == 2212, 算法分为两个步骤. 第一步, 将这个 2212 个数分为 1~ 212, 213 ~ 2212 2. 第一部分实际上是将 n 的规模缩小到 212. 假如知道如 ...

  5. ArcGIS Android SDK 中文标注乱码

    Android使用如下代码添加标注: TextSymbol ts = new TextSymbol(12, "名称", Color.RED);Graphic gp = new Gr ...

  6. ArcGIS GP应用-GP模型创建-缓冲区分析

    一.参考资料 http://www.cnblogs.com/HPhone/archive/2012/11/05/2755974.html 二.关键步骤 1.缓冲分析数据源可以选择:点.面.线 2.构建 ...

  7. 阿里云CentOS6.8安装MySQL5.6

    1.使用SSH Secure Shell工具连接阿里云服务器 2.使用SSH Secure File Transfer工具上传MySQL压缩包 3.解压MySQL压缩包到指定目录(需要在先/usr/l ...

  8. Python 正则表达式规则

    正则表达式的一些匹配规则: . :用于匹配任意一个字符,如 a.c 可以匹配 abc .aac .akc 等^ :用于匹配以...开头的字符,如 ^abc 可以匹配 abcde .abcc .abca ...

  9. poj_1464 动态规划

    题目大意 N个节点构成一棵树形结构,在其中若干个节点上放置士兵,与被放置士兵的节点相连的边会被士兵看守.问需要至少在多少个节点上放置士兵,才能使得N-1条边都被看守. 题目分析 题目描述的结构为树形, ...

  10. 快速解决:windows安装程序无法将windows配置为在此计算机的硬件上运行

    用手工运行msoobe.ext启用配置的方法, 快速解决:windows安装程序无法将windows配置为在此计算机的硬件上运行   我自己安装碰到的是蓝色这个错误,下面这个也有网友说用安装驱动等方法 ...