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

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. db2代理和优化

    DB2 的代理 (agent) 是位于 DB2 服务器中的服务于应用程序请求的一些进程或线程.当有外部应用程序连接至 DB2 实例提出访问请求时,DB2 的代理就会被激活去应答这些请求.一般 DB2 ...

  2. exp.validate.js

    简单实用的js基础数据验证 prototype /// <reference path="/Scripts/expand-fn/exp_validate.js" /> ...

  3. Application Initialization Module for IIS 7.5

    http://www.iis.net/downloads/microsoft/application-initialization IIS7.5也有Warm Up功能 让ASP.NET第一次Reque ...

  4. C++ string 类的 find 方法实例详解

    1.C++ 中 string 类的 find 方法列表 size_type std::basic_string::find(const basic_string &__str, size_ty ...

  5. 在springmvc中,获取Connection接口

    ServletContext context = request.getSession().getServletContext();WebApplicationContext wac = WebApp ...

  6. Hibernate框架配置

     API package com.hanqi.test; import static org.junit.Assert.*; import org.hibernate.SessionFactory; ...

  7. fn标签常用方法使用说明

    需要jstl.jar包,然后在jsp页头导入 <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix=& ...

  8. tab1

    <html> <head> <meta charset="UTF-8"> <title>tab</title> < ...

  9. .offsetLeft,.offsetTop

    *{ margin:0; padding:0} div {padding: 40px 50px;} #div1 {background: red;} #div2 {background: green; ...

  10. 转 状态压缩DP

    引入 首先来说说“状态压缩动态规划”这个名称,顾名思义,状态压缩动态规划这个算法包括两个特点,第一是“状态压缩”,第二是“动态规划”. 状态压缩: 从状态压缩的特点来看,这个算法适用的题目符合以下的条 ...