spring如何实现注入

spring如何实现注入

IOC(Inverse of Control)可翻译为“控制反转”,但大多数人都习惯将它称为“依赖注入”。在Spring中,通过IOC可以将实现类 、参数信息等配置在其对应的配置文件中 ,那么当需要更改实现类或参数信息时,只需要修改配置文件即可,这种方法在上例的基础上更进一步的降低了类与类之间的耦合。我们还可以对某对象所需要的其它对象进行注入 ,这种注入都是在配置文件中做的,Spring的IOC的实现原理利用的就是Java的反射机制,Spring还充当了工厂的角色,我们不需要自己建立工厂类 。Spring的工厂类会帮我们完成配置文件的读取、利用反射机制注入对象等工作,我们可以通过bean的名称获取对应的对象。

定义一个bean src/main/java/spring_ioc/JavaBean.java

package spring_ioc;/*** Created by tom on 2016/5/18.*/
public class JavaBean {String username;String password;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}

实例化一个类,利用反射,将其注入值 src/main/java/spring_ioc/SetValueByReflection.java

package spring_ioc;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;/*** Created by tom on 2016/5/18.*/
public class SetValueByReflection {/*** 实例化一个类,利用反射,将其注入值*/public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {JavaBean bean = new JavaBean();//获取指定类的指定方法,Class c = Class.forName("spring_ioc.JavaBean");Method method = c.getMethod("setUsername", new Class[]{String.class});//对带有指定参数的指定对象调用由此 Method 对象表示的底层方法,调用对象javaBean的setuserName方法,参数为"hello world"method.invoke(bean, "hello world");System.out.println(bean.getUsername());}
}

实例化一个类,利用反射,用个map来摸拟在xml获取的属性名及值 src/main/java/spring_ioc/SetValueByReflectionLoop.java

package spring_ioc;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;/*** Created by tom on 2016/5/18.*/
public class SetValueByReflectionLoop {static Logger log = LoggerFactory.getLogger(BeanFactory.class);public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException, IntrospectionException {//这个map对象用来模拟对属性文件解析获了的属性名与值Map<String, Object> map = new HashMap<>();map.put("username", "tomLuo");map.put("password", "954");Class bean = Class.forName("spring_ioc.JavaBean");Object obj = bean.newInstance();//获取对应class信息BeanInfo info = Introspector.getBeanInfo(bean);// 遍历指定类的属性PropertyDescriptor[] propertys = info.getPropertyDescriptors();for (int j = 0; j < propertys.length; j++) {System.out.println("属性:" + propertys[j].getName());}//获取其属性描述java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();Method mSet = null;for (int k = 0; k < pd.length; k++) {if (map.containsKey(pd[k].getName())) {Object value=map.get(pd[k].getName());//将对应的属性值取出来mSet = pd[k].getWriteMethod();log.info("{} {} {}", pd[k].getName(), pd[k].getWriteMethod().getName(), pd[k].getReadMethod().getName());//password setPassword getPasswordmSet.invoke(obj, value);//利用反射将567注入到bean 这儿实验将每个set方法的值都设置为567}}//将对象放入beanMap中,其中key为id值,value为对象JavaBean javaBean1 = (JavaBean) obj;System.out.println("userName=" + javaBean1.getUsername());System.out.println("password=" + javaBean1.getPassword());}
}

加载xml文件,利用反射,将其注入值 src/main/resources/config.xml

<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"><bean id="javaBean" class="spring_ioc.JavaBean"><property name="username" value="tom"/><property name="password" value="123"/></bean>
</beans>

Bean工厂主要用来解析xml文件,获取属性名及值,然后利用反射,将其注入值 src/main/java/spring_ioc/BeanFactory.java

package spring_ioc;import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;/*** Created by tom on 2016/5/18.*/
public class BeanFactory {static Logger log = LoggerFactory.getLogger(BeanFactory.class);private Map<String, Object> beanMap = new HashMap<String, Object>();/*** bean工厂的初始化** @param xml*/public void init(String xml) {try {//读取指定的配置文件SAXReader reader = new SAXReader();//从class目录下获取指定的配置文件ClassLoader classLoader = Thread.currentThread().getContextClassLoader();InputStream inputStream = classLoader.getResourceAsStream(xml);//读取xml文件Document document = reader.read(inputStream);//获取跟节点Element root = document.getRootElement();//遍历bean节点Element foo;for (Iterator iteBean = root.elementIterator("bean"); iteBean.hasNext(); ) {foo = (Element) iteBean.next();//获取bean的属性id和classAttribute id = foo.attribute("id");Attribute cls = foo.attribute("class");//利用java反射机制,通过class的名称获取Class对象log.debug("{}", cls.getText());Class bean = Class.forName(cls.getText());//获取对应class信息java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);//获取其属性描述java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();//设置值的方法Method mSet = null;//创建一个对象(创建此 Class 对象所表示的类的一个新实例。如同用一个带有一个空参数列表的 new 表达式实例化该类。如果该类尚未初始化,则初始化这个类。)Object obj = bean.newInstance();//遍历该bean的property属性for (Iterator iteProperty = foo.elementIterator("property"); iteProperty.hasNext(); ) {Element elementProperty = (Element) iteProperty.next();//获取该property的name属性Attribute name = elementProperty.attribute("name");//读取该属性值String value = elementProperty.attribute("value").getText();//String value = null;//获取该property的子元素value的值//for(Iterator iteValue = elementProperty.elementIterator("value");iteValue.hasNext();){//      Element elementValue = (Element)iteValue.next();//      value = elementValue.getText();//      break;//}for (int k = 0; k < pd.length; k++) {log.info(pd[k].getName());if (pd[k].getName().equalsIgnoreCase(name.getText())) {mSet = pd[k].getWriteMethod();//log.info(mSet.getName());//利用Java的反射机制调用对象的某个set方法,并将值设置进去mSet.invoke(obj, value);//通过invoke方法来调用特定对象的特定方法,实现的原理都是基于Java的反射机制}}}//将对象放入beanMap中,其中key为id值,value为对象beanMap.put(id.getText(), obj);}} catch (Exception e) {e.printStackTrace();}}/*** 通过bean的id获取bean的对象.** @param beanName bean的id* @return 返回对应对象*/public Object getBean(String beanName) {Object obj = beanMap.get(beanName);return obj;}public static void main(String[] args) {BeanFactory factory = new BeanFactory();factory.init("config.xml");JavaBean javaBean = (JavaBean) factory.getBean("javaBean");System.out.println("userName=" + javaBean.getUsername());System.out.println("password=" + javaBean.getPassword());}
}

可以看到,虽然在main()方法中没有对属性赋值,但属性值已经被注入,在BeanFactory类中的Class bean = Class.forName(cls.getText()); 通过类名来获取对应的类,mSet.invoke(obj, value);通过invoke方法来调用特定对象的特定方法,实现的原理都是基于Java的反射机制

源代码访问: https://github.com/tomlxq/job-test/tree/master/java-base

posted on 2016-05-19 09:43 tomLuo 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/tomlxq/p/5507626.html

spring如何实现注入相关推荐

  1. Spring——Filter过滤器注入Bean时注入失败[NULL]

    问题描述 Spring中Filter注入Bean时注入失败,Bean一直为空. @Slf4j @Component public class RestAuthFilter extends FormAu ...

  2. Spring 多线程下注入bean问题

    问题 Spring中多线程注入userThreadService注不进去,显示userThreadService为null异常 代码如下: public class UserThreadTask im ...

  3. factorybean 代理类不能按照类型注入_《Spring入门经典》:使用Spring进行依赖注入

    第二章:使用Spring进行依赖注入 重点:配置并使用Spring容器 使用不同类型的配置元数据来配置Spring容器 理解依赖解析 了解自动装配的优缺点 在容器中执行显式Bean查找 学习不同的Be ...

  4. 在ABAP里模拟实现Java Spring的依赖注入

    Dependency Injection- 依赖注入,在Java Spring框架中有着广泛地应用.通过依赖注入,我们不必在应用代码里繁琐地初始化依赖的资源,非常方便. 那么ABAP能否从语言层面上也 ...

  5. Spring Setter依赖注入示例

    学习如何编写Spring Setter依赖注入示例 . Setter注入是Spring依赖注入的一种 . Spring支持字段注入,Setter注入以及构造函数注入,以将依赖项注入Spring托管的b ...

  6. Spring字段依赖注入示例

    学习如何编写Spring Field Injection示例 . 字段注入是Spring框架 依赖注入的一种 . 在本教程中,我们将编写几个类,并看一看现场注入工程. 有关Spring依赖注入的更多信 ...

  7. Spring构造函数依赖注入示例

    欢迎使用Spring构造函数依赖注入示例指南. 基于构造器的依赖注入是Spring 依赖注入的一种 . 依赖注入的另一种类型是Setter注入和字段注入. 有关Spring依赖注入的更多信息: Spr ...

  8. spring三种注入方式

    设置Spring的作用域 或者使用枚举值设置 单例和多里使用场景 自动注入 @Primary 一个接口有多个实现被spring管理吗,在依赖注入式,spring会不知道注入哪个实现类就会抛出NoUni ...

  9. 据说,80%的人没有真正理解了Spring的依赖注入

    前言 提起Spring,大家肯定不陌生,它是每一个Java开发者绕不过去的坎.Spring 框架为基于 java 的企业应用程序提供了一整套解决方案,方便开发人员在框架基础快速进行业务开发. 在官网中 ...

  10. Spring框架----Spring的依赖注入

    1.spring的依赖注入的概念 依赖注入:dependency Injection IOC的作用:降低程序之间的依赖关系,但不是消除. 依赖关系的管理:以后都交给了spring来维护 在当前类中需要 ...

最新文章

  1. Go modules基础精进,六大核心概念全解析(上)
  2. linux mono
  3. mybatis返回map操作
  4. NOIP Mayan游戏
  5. 一篇能加深理解linux 虚拟文件系统的博文
  6. spring social_Spring Social入门
  7. 移动通信考前预习_第2章_蜂窝技术
  8. 小甲鱼 OllyDbg 教程系列 (二) :从一个简单的实例来了解PE文件
  9. yii+php+当前目录,Yii应用的目录结构和入口脚本
  10. phpstudy 线上添加域名
  11. JavaScript 类型判断的那些事
  12. form表单提交大量input,php接收不全
  13. android代码设置drawable,Android:Textview 通过代码设置 Drawable
  14. c语言中存储点分十进制IP地址
  15. ArcGIS批量计算图层中矢量要素面积——ArcMap
  16. 样本峰度(kurtosis)与随机变量的峰度及四阶统计量之间的关系和计算估计
  17. MATLAB知识小结
  18. 带圈的11-15如何打出
  19. 光学镜头分类及相机接口(附镜头规格书)
  20. 作为父亲,给儿子留下些什么? | 黄华书房

热门文章

  1. COOKIE和Session的原理及异同
  2. iOS 程序 main函数之前发生什么
  3. 解决atom安装emmet的问题
  4. OSPF外部实验详解
  5. 【性能】雅虎军规(14条常用)笔记
  6. linux服务器svn安装配置
  7. Unity3d UGUI 通用Confirm确认对话框实现(Inventory Pro学习总结)
  8. Introduction to Oracle9i: SQL------- left join 和 left outer join 的区别
  9. 左边工具栏 隐藏_203 【Ps基础】 工具栏
  10. PTA:6-2顺序表操作集(20分)