spring IOC 机制模拟实现

本文通过实例介绍了Java反射机制的基本用法,包括运行时获取类信息及调用方法等内容,并探讨了依赖注入(IOC)的概念及其如何降低代码间的耦合度。

最近对spring IOC AOP 机制实现原理了解了下,在此做下整理,希望能给需要的朋友予以帮助。整理的资料来自互联网,文章开头是我写的测试代码例子,可以直接导入eclipse,别忘了导入dom4jjar包。

 

例子代码下载链接:http://download.youkuaiyun.com/source/630961

 

利用java的反射和动态代理实现IOC

       在Java中,其反射和动态代理机制极其强大,我们可以通过其反射机制在运行时获取信息。而代理是一种基本的设计模式,它是一种为了提供额外的或不同的操作而插入到真实对象中的某个对象。而Java的动态代理在代理上更进一步,既能动态的创建代理对象,又能动态的调用代理方法。Java的反射和动态代理机制,使Java变得更加强大。

       Spring框架这几年风头正劲,虽然使用者众多,但真正了解其内部实现原理的朋友却并不是很多。其实,了解它的内部实现机制和设计思想是很有必要的大家都知道,Spring框架的IOC和AOP部分功能强大,很值得我们学习。那么让我们在这两篇文章中分别详细的学习IOC和AOP的实现吧。

在本文中,主要讲述的是用Java的反射机制实现IOC。下面,让我们开始IOC之旅吧!

一.             Java反射机制概述与初探

Java的反射机制是Java语言的一个重要特性,Java具有的比较突出的动态机制就是反射(reflection)。通过它,我们可以获取如下信息:

1) 在运行时判断任意一个对象所属的类;

2) 在运行时获取类的对象;

3) 在运行时获得类所具有的成员变量和方法等。

下面让我们通过调用一个Java Reflection API的演示实例来见识一下反射机制的强大。

首先在IDE中建立名为reflection_proxy的Java工程,并建立存放源文件的目录src,并在src目录下分别建立org.amigo. reflection目录和org.amigo.proxy目录来分别存放代理和反射的实例。我们在reflection目录下建立ReflectionTest.java文件,在该文件中编写代码来演示Java Reflection API的使用。该类的代码如下所示:

package  org.amigo.reflection;

import  java.awt.Button;
import  java.lang.reflect.Method;
import  java.util.Hashtable;

/** */ /**
 *初探Java的反射机制.   
 *
@author<a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
 *Creationdate:2007-10-2-上午10:13:48
 
*/

publicclass ReflectionTest 
{

    
/** *//**
     *@paramargs
     
*/

    publicstaticvoid main(String[] args) 
throws Exception {
        ReflectionTest reflection 
= new ReflectionTest();
        reflection.getNameTest();
        System.out.println(
"");
        reflection.getMethodTest();
    }


    
/** *//**
     *Class的getName()方法测试.
     *@throwsException
     
*/

    publicvoid getNameTest() 
throws Exception {
        System.out.println(
"===========begin getNameTest============");
        String name 
= "阿蜜果";
        Class cls 
= name.getClass();
        System.out.println(
"String类名: " + cls.getName());
        Button btn 
= new Button();
        Class btnClass 
= btn.getClass();
        System.out.println(
"Button类名: " + btnClass.getName());
        Class superBtnClass 
= btnClass.getSuperclass();
        System.out.println(
"Button的父类名: " + superBtnClass.getName());
        Class clsTest 
= Class.forName("java.awt.Button");
        System.out.println(
"clsTest name: " + clsTest.getName());
        System.out.println(
"===========end getNameTest============");
    }

    
    
/** *//**
     *Class的getMethod()方法测试.
     *@throwsException
     
*/

    publicvoid getMethodTest() 
throws Exception {
        System.out.println(
"===========begin getMethodTest==========");
        Class cls 
= Class.forName("org.amigo.reflection.ReflectionTest");
        Class ptypes[] 
= new Class[2];
        ptypes[
0= Class.forName("java.lang.String");
        ptypes[
1= Class.forName("java.util.Hashtable");
        Method method 
= cls.getMethod("testMethod", ptypes);
        Object args[] 
= new Object[2];
        args[
0= "hello, my dear!";
        Hashtable
<String, String> ht = new Hashtable<String, String>();
        ht.put(
"name""阿蜜果");
        args[
1= ht;

        String returnStr 
= (String) method.invoke(new ReflectionTest(), args);
        System.out.println(
"returnStr= " + returnStr);
        System.out.println(
"===========end getMethodTest==========");
    }


    
public String testMethod(String str, Hashtable ht) throws Exception {
        String returnStr 
= "返回值";
        System.out.println(
"测试testMethod()方法调用");
        System.out.println(
"str= " + str);
        System.out.println(
"名字= " + (String) ht.get("name"));
        System.out.println(
"结束testMethod()方法调用");
        
return returnStr;
}

}

     运行该例,可在控制台看到如下内容:

===========begin getNameTest============

String类名: java.lang.String

Button类名: java.awt.Button

Button的父类名: java.awt.Component

clsTest name: java.awt.Button

===========end getNameTest============

===========begin getMethodTest==========

测试testMethod()方法调用

str= hello, my dear!

名字= 阿蜜果

结束testMethod()方法调用

returnStr= 返回值

===========end getMethodTest==========

    分析运行结果,我们可以发现,Java的反射机制使得我们在运行时能够判断一个对象所属的类,获取对象的方法并得其进行调用,并获取方法的返回结果等功能。

二.             IOC使用的背景

在我们日常的设计中,类与类之间存在着千丝万缕的关系,如果两个类存在着强耦合关系,那么在维护时,一个类的修改很可能会牵动另一个类的关联修改,从而使得我们的维护工作步履维艰。下面让我们来看这样的一个强耦合反面例子。

首先我们建立一个Chinese.java类,该类的sayHelloWorld(String name)方法,用中文对名为name的人问好,其内容如下:

package  org.amigo.reflection;

/** */ /**
 *中国人类.   
 *
@author<a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
 *Creationdate:2007-10-2-上午10:37:17
 
*/

publicclass Chinese 
{

    
/** *//**
     *用中文对某人问好.
     *@paramname姓名
     
*/

    publicvoid sayHelloWorld(String name) 
{
       String helloWorld 
= "你好," + name;
       System.out.println(helloWorld);
    }

}

 

下面我们接着建立一个American.java类,该类的sayHelloWorld(String name)方法,用英文对名为name的人问好,其内容如下:

package  org.amigo.reflection;

/** */ /**
 *美国人类.   
 *
@author<a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
 *@version1.0
 *Creationdate:2007-10-2-上午10:41:27

 
*/

publicclass American 
{

    
/** *//**
     *用英文对某人问好.
     *@paramname姓名
     
*/

    publicvoid sayHelloWorld(String name) 
{
       String helloWorld 
= "Hello," + name;
       System.out.println(helloWorld);
    }

}

 

    最后我们编写一个测试类对这两个类的sayHelloWorld(String name)方法进行测试,下面是该类的内容:

package  org.amigo.reflection;

/** */ /**
 *HelloWorld测试.
 *
@author<a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
 *Creationdate:2007-10-2-上午10:45:13
 
*/

publicclass HelloWorldTest 
{

    
/** *//**
     *测试Chinese和American的sayHelloWorld()方法.
     *@paramargs
     *
@author<a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
     *Creationdate:2007-10-2-上午10:43:51
     
*/

    publicstaticvoid main(String[] args) 
{
       Chinese chinese 
= new Chinese();
       chinese.sayHelloWorld(
"阿蜜果");
       
       American american 
= new American();
       american.sayHelloWorld(
"Amigo");
    }

}


    观察HelloWorldTest我们可以很清楚的看到,该类与Chinese.java类和American.java类都存在强

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值