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

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. IOS 登陆判断问题

    有一个登陆界面,还有一个包含多个选项卡的界面在ViewController.m中登陆按钮的代码如下 UIViewController *controller=[[Tabbarcontroller al ...

  2. Maven_根据不同个环境打包, 获取不同的配置文件等等

    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 3 ...

  3. Spring_手动获取Bean

    1.SpringContextHolder.java package com.lkb.util; import org.springframework.context.ApplicationConte ...

  4. html中隐藏域hidden的作用介绍及使用示例

    基本语法: <input type="hidden" name="field_name" value="value"> 作用:  ...

  5. Js中找任意对象的原型方法及改造原型

    Java中有运行时类型识别,js可以很方便的模仿这个特性,因为所有js对象都有一个属性constructor(构造器),表示这个对象的构造方法,原型与构造方法同名,所以可以通过这儿知道任意对象的原型名 ...

  6. 关于百度分享——bdCustomStyle一点bug

    最近碰到一个项目,因为用上百度分享,出现了奇怪的bug. 具体是,当访问JSP页面时,js脚本会执行一次,而java脚本执行了两次. 最后排查发现是百度分享js脚本的问题,把"bdCusto ...

  7. php中使用while遍历二维数组的方法

    <?php $contact=array( 'gao'=>array('ID'=>1,'name'=>'高某','company'=>'A公司','addr'=>' ...

  8. c++之map

    题目描述:     哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮 ...

  9. Transform a BST to greater sum tree

    Given a BST, transform it into greater sum tree where each node contains sum of all nodes greater th ...

  10. iTop各数据表联系图(持续更新中)