首先我有一个数据访问层接口:

public interface StudentDao {

void save(Student stu);

}

和实现类:

1.mysql实现类

public class StudentDaoImplByMySql implements StudentDao{

public void save(Student stu){

System.out.println(stu.getName()+"被Orcacle保存了!");

}

}

2.oracle实现类

public class StudentDaoImplByOrcacle implements StudentDao{

public void save(Student stu){

System.out.println(stu.getName()+"被MySql保存了!");

}

}

然后我的业务逻辑层接口:

public interface StudentService {

public void add(Student stu);

}

我的业务逻辑层实现类(里面有一个数据访问层的接口):

public class StudentServiceImpl implements StudentService {

private StudentDao dao;

public void add(Student stu) {

dao.save(stu);

}

public StudentDao getDao() {   return dao;  }

public void setDao(StudentDao dao) {   this.dao = dao;  }

}

然后主要的是我的工具类Application:

public class Application {

private Map<String, Object> map = null;

public Application() throws IOException, InstantiationException,    IllegalAccessException, ClassNotFoundException, DocumentException,    IntrospectionException, IllegalArgumentException,    InvocationTargetException {

map = new HashMap<String, Object>();

// 使用dom4J读取XML文件

SAXReader read = new SAXReader();

// 读取文件

Document document = read.read(Application.class.getClassLoader().getResourceAsStream("app.xml"));

// 获取根节点

Element rootElement = document.getRootElement();

// 获取根节点下的子节点集合

List<Element> elements = rootElement.elements();

for (Element element : elements) {

// id为标识名(随意起),class为类型,根据id值找到class

  String id = element.attribute("id").getValue();

  String clas = element.attribute("class").getValue();

// 得到Class类名后得到这个类的实例对象

Object object = Class.forName(clas).newInstance();

// 继续循环子节点下的子节点

for (Element element2 : (List<Element>) element.elements()) {

// studentServiceImpl实现类里有一个属性是studentDao层的接口

// 这个name的值必须和studentServiceImpl的属性名一致

  String name = element2.attribute("name").getValue();

// ref指向dao的一个实现类StudentDaoImpl的标识名(也就是id)

String ref = element2.attribute("ref").getValue();

// 属性描述符 参数一个是接口的别名:StudentDao dao

// 一个是实现类的实例cn.jnti.dao.StudentDaoImplByMySql

PropertyDescriptor pd = new PropertyDescriptor(name,object.getClass());

// WriteMethod就是public void setDao(StudentDao dao)的方法,注入就是这样来的

  Method writeMethod = pd.getWriteMethod();

// 由于我的map集合里key值为id,value值为对象,此时的ref为StudentDaoImplByMySql

// StudentDaoImplByMySql正是集合里cn.jnti.dao.StudentDaoImplByMySql对象的key

// object是对象,map.get(ref)拿到此对象的实例

writeMethod.invoke(object, map.get(ref));

}

//map集合里放的全部是代理对象

Handle han = new Handle(object);

//返回一个代理对象

object = Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(), han);

//把代理对象放入集合

map.put(id, object);

}

}

public Object getBean(String name) {

//返回的是一个代理对象

return map.get(name);

}

}

*************

我的handle类:

*************

public class Handle implements InvocationHandler{

private Object obj;

public Handle(Object obj) {

    this.obj = obj;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args)    throws Throwable {

//过滤掉service层的执行前和执行后方法

if(method.toString().contains("Service")){

return method.invoke(obj, args);

}

//只在dao层添加执行前和执行后方法

doBefor();

Object object=method.invoke(obj, args);

doAfter();

return object;

}

private void doBefor() {   System.out.println("执行之前!");  }

private void doAfter() {   System.out.println("执行之后");  }

}

***************

我的app.xml

****************

<?xml version="1.0" encoding="UTF-8"?>

<beans>

<bean id="StudentDaoImplByMySql" class="cn.jnti.dao.StudentDaoImplByMySql"></bean>

<bean id="StudentDaoImplByOrcacle" class="cn.jnti.dao.StudentDaoImplByOrcacle"></bean>

<bean id="StudentServiceImpl" class="cn.jnti.service.StudentServiceImpl">

<property name="dao" ref="StudentDaoImplByMySql"></property>

</bean>

</beans>

****************

我的测试类:

public class TestStudent {
 StudentService service=null;
    @Test
 public void studentAdd() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, DocumentException, IntrospectionException, InvocationTargetException{
     Application app=new  Application();
      service =  (StudentService) app.getBean("StudentServiceImpl");
  Student stu=new Student("小明",18);
  //返回的是一个代理对象,调用代理对象的方法时里面会走doBefor,和doAfter
  service.add(stu);
 }

}

Sring控制反转(Inversion of Control,Ioc)也被称为依赖注入(Dependency Injection,DI)原理用反射和代理实现的更多相关文章

  1. 控制反转Inversion of Control (IoC) 与 依赖注入Dependency Injection (DI)

    控制反转和依赖注入 控制反转和依赖注入是两个密不可分的方法用来分离你应用程序中的依赖性.控制反转Inversion of Control (IoC) 意味着一个对象不会新创建一个对象并依赖着它来完成工 ...

  2. 控制反转 (inversion of control)

    The inversion of control (IoC) pattern is abstract; it says that one should move dependency creation ...

  3. 设计模式之————依赖注入(Dependency Injection)与控制反转(Inversion of Controller)

    参考链接: 依赖注入(DI) or 控制反转(IoC) laravel 学习笔记 —— 神奇的服务容器 PHP 依赖注入,从此不再考虑加载顺序 名词解释 IoC(Inversion of Contro ...

  4. Spring 控制反转容器(Inversion of Control – IOC)

    系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of Contro ...

  5. 深入浅出spring IOC中三种依赖注入方式

    深入浅出spring IOC中三种依赖注入方式 spring的核心思想是IOC和AOP,IOC-控制反转,是一个重要的面向对象编程的法则来消减计算机程序的耦合问题,控制反转一般分为两种类型,依赖注入和 ...

  6. 转:深入浅出spring IOC中四种依赖注入方式

    转:https://blog.csdn.net/u010800201/article/details/72674420 深入浅出spring IOC中四种依赖注入方式 PS:前三种是我转载的,第四种是 ...

  7. Spring IOC(三)依赖注入

    本系列目录: Spring IOC(一)概览 Spring IOC(二)容器初始化 Spring IOC(三)依赖注入 Spring IOC(四)总结 目录 1.AbstractBeanFactory ...

  8. Spring IOC(五)依赖注入

    Spring IOC(五)依赖注入 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) 一.autowire 五种注入方式测试 ...

  9. 个人对【依赖倒置(DIP)】、【控制反转(IOC)】、【依赖注入(DI)】浅显理解

    一.依赖倒置(Dependency Inversion Principle) 依赖倒置是面向对象设计领域的一种软件设计原则.(其他的设计原则还有:单一职责原则.开放封闭原则.里式替换原则.接口分离原则 ...

  10. IOC-控制反转(Inversion of Control),也成依赖倒置(Dependency Inversion Principle)

    基本简介 IoC 亦称为 “依赖倒置原理”("Dependency Inversion Principle").差不多所有框架都使用了“倒置注入(Fowler 2004)技巧,这可 ...

随机推荐

  1. C语言中计算变量占用内存空间

    C语言中计算变量占用内存空间 在C语言中通常用[sizeof]运算符计算变量占内存空间,如下面的例子:

  2. Hadoop、Zookeeper、Hbase分布式安装教程

    参考: Hadoop安装教程_伪分布式配置_CentOS6.4/Hadoop2.6.0   Hadoop集群安装配置教程_Hadoop2.6.0_Ubuntu/CentOS ZooKeeper-3.3 ...

  3. 纪念逝去的岁月——C++实现一个队列(使用类模板)

    1.代码 2.运行结果 1.代码 #include <stdio.h> #include <string.h> template <typename T> clas ...

  4. OpenSceneGraph学习笔记

    VirtualPlanetBuilder编译方法 转自:http://www.boyunjian.com/do/article/snapshot.do?uid=7327932418831703800 ...

  5. Hashtable在ViewState中无法增加值

    在我调试程序的时候,我发现WebForm 2.0和MVC3解析ViewState的方式不同,同样的代码,在Weorm中管用,在MVC中不起作用. private Hashtable ht { get ...

  6. CSS Bugs 解决方案

    说明:本文档兼容性测试基础环境为:windows系统:IE6-IE10, Firefox6.0, Chrome13.0, Safari5.1, Opera11.51 Bugs及解决方案列表(以下实例默 ...

  7. IE 9 以下兼容HTML5

    <head> <meta name="viewport" content="width=device-width,initial-scale=1.0&q ...

  8. php引用&符号详解——————给变量起小名

    学习了这篇博客[http://blog.csdn.net/jiedushi/article/details/6428585] php中引用采用的是“写时拷贝”的原理,就是除非发生写操作,指向同一个地址 ...

  9. 用外部表的方式查询当天数据库alert日志文件

    1环境准备 2查询ORA-开头的错误

  10. 使用javascript实现在页面打印的效果的三种方式

    <div id="console"></div> <script type="text/javascript"> var c ...