注入bean有两种方式:

  1. 注入其他bean
  2. 方式一
  3. <bean id="orderDao" class="cn.itcast.service.OrderDaoBean"/>
  4. <bean id="orderService" class="cn.itcast.service.OrderServiceBean">
  5. <property name="orderDao" ref="orderDao"/>
  6. </bean>
  7. 方式二(使用内部bean,但该bean不能被其他bean使用)
  8. <bean id="orderService" class="cn.itcast.service.OrderServiceBean">
  9. <property name="orderDao">
  10. <bean class="cn.itcast.service.OrderDaoBean"/>
  11. </property>
  12. </bean>

  

一般我们的工程在service层依赖dao层的实现来实现业务逻辑。

service层:

  1. public class PersonServiceImpl implements PersonService {
  2.  
  3. private PersonDao personDao;
  4.  
  5. @Override
  6. public void save() {
  7. personDao.save();
  8. System.out.println("service : " + " save 方法");
  9. }
  10. public PersonDao getPersonDao() {
  11. return personDao;
  12. }
  13. public void setPersonDao(PersonDao personDao) {
  14. this.personDao = personDao;
  15. }
  16. }

  

dao层:

  1. public class PersonDaoImpl implements PersonDao {
  2. @Override
  3. public void save() {
  4. System.out.println("dao层的save方法");
  5. }
  6. }

  

beans.xml的配置

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  6.  
  7. <bean id="personDaoImpl" class="cn.gbx.dao.PersonDaoImpl"></bean>
  8. <bean id="personServiceImpl" class="cn.gbx.serviceimpl.PersonServiceImpl" >
  9. <property name="personDao" ref="personDaoImpl"></property>
  10. </bean>
  11. </beans>

  

测试方法:

  1. public class SpringTest {
  2. @Test
  3. public void spring1() {
  4. ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
  5. PersonService ps = (PersonService)ctx.getBean("personServiceImpl");
  6. ps.save();
  7. }
  8. }

  

然后我们就实现了Spring对bean对象的依赖注入。 service层所依赖的dao层的PersonDao对象不是由service本身去创建管理,而是交给了第三方容器Spring去管理。

那么Spring是如何管理的呢?

我们可想而知

1: 首先必须解析XML 将 <bean>标签和 <property>标签都解析出来

2: 利用反射实例话对象

3: 利用内省将实例化完成的对象注入到有依赖的对象里面

我们可以自己模拟实现:

  1. package cn.gbx.myExample;
  2.  
  3. import java.beans.BeanInfo;
  4. import java.beans.IntrospectionException;
  5. import java.beans.Introspector;
  6. import java.beans.PropertyDescriptor;
  7. import java.lang.reflect.Method;
  8. import java.net.URL;
  9. import java.util.ArrayList;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Map;
  13.  
  14. import org.apache.commons.beanutils.ConvertUtils;
  15. import org.dom4j.Document;
  16. import org.dom4j.DocumentException;
  17. import org.dom4j.Element;
  18. import org.dom4j.XPath;
  19. import org.dom4j.io.SAXReader;
  20.  
  21. public class MyClassPathXmlApplicationContext {
  22.  
  23. private List<DefBean> defBeans = new ArrayList<DefBean>(); //存储<bean>标签的信息
  24. private Map<String, Object> singltons = new HashMap<String, Object>(); //存储读出来的对象
  25.  
  26. public MyClassPathXmlApplicationContext() {
  27. super();
  28. }
  29.  
  30. public MyClassPathXmlApplicationContext(String filename) {
  31. this.readXML(filename);
  32. this.instanceBean();
  33. this.injectProperty();
  34. }
  35. //利用内省将属性注入
  36. private void injectProperty() {
  37. for (DefBean defBean : defBeans) {
  38. Object bean = singltons.get(defBean.getId());
  39. if (bean != null) {
  40. //要想将依赖的对象注入,我们就要通过内省来操作对象的属性
  41. try {
  42. BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
  43. PropertyDescriptor[] ps = beanInfo.getPropertyDescriptors();
  44.  
  45. for (DefProperty p : defBean.getDefPropertys()) {
  46. for (PropertyDescriptor propertyDes : ps) {
  47. if (propertyDes.getName().equals(p.getName())) {
  48. Method setter = propertyDes.getWriteMethod();
  49. if (setter != null) {
  50. Object value = null;
  51. if (p.getRef() != null && !"".equals(p.getRef())) {
  52. value = singltons.get(p.getRef());
  53. } else { //基本数据类型利用beanUtils实现转化
  54. value = ConvertUtils.convert(p.getValue(),propertyDes.getPropertyType());
  55. }
  56. setter.setAccessible(true); //这样即使set方法是私有的都可以访问
  57. setter.invoke(bean, value); //把引用对象注入到bean属性里面
  58. }
  59. break;
  60. }
  61. }
  62. }
  63. } catch (Exception e) {
  64. // TODO Auto-generated catch block
  65. e.printStackTrace();
  66. }
  67. }
  68. }
  69.  
  70. }
  71. //利用反射实例化对象
  72. private void instanceBean() {
  73. for (DefBean bean : defBeans) {
  74. //输出测试读取的xml
  75. /*System.out.println(bean.getId() + " : " + bean.getClassName());
  76. System.out.println("------------------------");
  77. for (DefProperty p : bean.getDefPropertys()) {
  78. System.out.println("Property : name = " + p.getName() + " : ref = " + p.getRef());
  79. }
  80. */
  81.  
  82. if (bean.getClassName() != null && !"".equals(bean.getClassName())) {
  83. try {
  84. singltons.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());
  85. } catch (Exception e) {
  86. e.printStackTrace();
  87. }
  88. }
  89. }
  90. }
  91.  
  92. private void readXML(String filename) {
  93. SAXReader reader = new SAXReader();
  94. Document document = null;
  95. URL xmlPath = this.getClass().getClassLoader().getResource(filename);
  96. try {
  97. document = reader.read(xmlPath);
  98. //创建命名空间
  99. Map<String, String> nsMap = new HashMap<String, String>();
  100. nsMap.put("ns", "http://www.springframework.org/schema/beans");
  101.  
  102. //创建查询路径
  103. XPath xsub = document.createXPath("//ns:beans/ns:bean");
  104. xsub.setNamespaceURIs(nsMap); // 设置命名空间
  105.  
  106. List<Element> elements = xsub.selectNodes(document);
  107.  
  108. DefBean defBean = null;
  109. for (Element e : elements) {
  110. String id = e.attributeValue("id");
  111. String className = e.attributeValue("class");
  112. defBean = new DefBean(id, className);
  113.  
  114. //为<bean>节点设置查询路径
  115. XPath xPropertySub = e.createXPath("ns:property");
  116. xPropertySub.setNamespaceURIs(nsMap);
  117. List<Element> propertys = xPropertySub.selectNodes(e);
  118.  
  119. DefProperty defProperty = null;
  120. for (Element e2 : propertys) {
  121. String name = e2.attributeValue("name");
  122. String ref = e2.attributeValue("ref");
  123. String value = e2.attributeValue("value");
  124. defProperty = new DefProperty(name, ref, value);
  125. defBean.getDefPropertys().add(defProperty);
  126. }
  127.  
  128. defBeans.add(defBean);
  129. }
  130. } catch (Exception e) {
  131. e.printStackTrace();
  132. }
  133.  
  134. }
  135. public Object getBean(String key) {
  136. return singltons.get(key);
  137. }
  138.  
  139. }

  

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  6.  
  7. <bean id="personDaoImpl" class="cn.gbx.dao.PersonDaoImpl"></bean>
  8. <bean id="personServiceImpl" class="cn.gbx.serviceimpl.PersonServiceImpl" >
  9. <property name="personDao" ref="personDaoImpl"></property>
  10. <property name="name" value="ok-gbx"></property>
  11. <property name="id" value="22"></property>
  12. </bean>
  13. </beans>

  

Spring的DI(Ioc) - 注入bean 和 基本数据类型的更多相关文章

  1. Spring的DI(Ioc) - 注入集合类型

    1: 首先给service添加集合类型的属性,并提供getter, setter package cn.gbx.serviceimpl; import java.util.ArrayList; imp ...

  2. [转载]Spring下IOC容器和DI(依赖注入) @Bean及@Autowired

    Spring下IOC容器和DI(依赖注入) @Bean及@Autowired自动装配 bean是什么 bean在spring中可以理解为一个对象.理解这个对象需要换一种角度,即可将spring看做一门 ...

  3. Spring框架(3)---IOC装配Bean(注解方式)

    IOC装配Bean(注解方式) 上面一遍文章讲了通过xml来装配Bean,那么这篇来讲注解方式来讲装配Bean对象 注解方式需要在原先的基础上重新配置环境: (1)Component标签举例 1:导入 ...

  4. Spring源码-IOC部分-Bean实例化过程【5】

    实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...

  5. spring的DI.IoC是什么

    最近要搞spring的单元测试,不得已啊啊啊啊啊啊啊啊啊又要开始搞spring…… 日目晶…… 搞这几个概念,先甩一部分代码: UserDao 接口 package com.itheima.ioc; ...

  6. 3、Spring的DI依赖注入

    一.DI介绍 1.DI介绍 依赖注入,应用程序运行依赖的资源由Spring为其提供,资源进入应用程序的方式称为注入. Spring容器管理容器中Bean之间的依赖关系,Spring使用一种被称为&qu ...

  7. Spring框架(2)---IOC装配Bean(xml配置方式)

    IOC装配Bean (1)Spring框架Bean实例化的方式提供了三种方式实例化Bean 构造方法实例化(默认无参数,用的最多) 静态工厂实例化 实例工厂实例化 下面先写这三种方法的applicat ...

  8. Spring的几种注入bean的方式

    在Spring容器中为一个bean配置依赖注入有三种方式: · 使用属性的setter方法注入  这是最常用的方式: · 使用构造器注入: · 使用Filed注入(用于注解方式).   使用属性的se ...

  9. Spring(三)之Ioc、Bean、Scope讲解

    Spring容器是Spring Framework的核心.容器将创建对象,将它们连接在一起,配置它们,并管理从创建到销毁的整个生命周期.Spring容器使用DI来管理组成应用程序的组件.这些对象称为S ...

随机推荐

  1. split function of Perl,Python,Awk

    使用中常用到Perl,Python,AWK,R, 虽然Java,C,C++,Vala也学过但是就是不喜欢,你说怎么办. 看来一辈子脚本的命. Perl @rray = split /PATTERN/, ...

  2. php const define 区别有那些呢?

    (1) 编译器处理方式不同 define宏是在预处理阶段展开. const常量是编译运行阶段使用. (2) 类型和安全检查不同 define宏没有类型,不做任何类型检查,仅仅是展开. const常量有 ...

  3. ECshop中defined('IN_ECS')的实现原理

    在PHP中经常看到如下代码   if (!defined('IN_ECS'))   {       die('Hacking attempt');   }   实现的原因以及原理如下:     ecs ...

  4. java 1G大文件复制

    对比几种复制方法 复制的文件是980m的txt文件 1.  FileChannel 方法 代码: public static void mappedBuffer() throws IOExceptio ...

  5. 怎么查看jar包版本

    jar包根目录里的META-INF目录下的MANIFEST.MF文件里一般有会记录版本信息,可以到这个文件里查看 打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录,这个目录 ...

  6. Reflector8.5 .net反编译工具 破解教程

    一.断网 二.打开软件.打开注册机 三. 四. 五. 六. 七. 八.

  7. JAVA基础知识之JVM-——反射和泛型

    泛型和Class类 在反射中使用泛型Class<T>可以避免强制类型转换,下面是一个简单例子,如果不使用泛型的话,需要显示转换, package aop; import java.util ...

  8. oracle 导出导入常见问题

    oracle 导入导出常见有两种方法 EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用.EXPDP和IMPDP是服务端的工具程序,他们只能在ORACLE服务端使用,不能在客户 ...

  9. java实现UDP协议传输DatagramSocket

    摘自:http://blog.csdn.net/wintys/article/details/3525643/ Server端. package com.topca.server; import ja ...

  10. IOSanimationDidStop

    -animationDidStop:finished: 方法中的flag参数表明了动画是自然结束还是被打断,我们可以在控制台打印出来.如果你用停止按钮来终止动画,它会打印NO,如果允许它完成,它会打印 ...