`
xifangyuhui
  • 浏览: 189018 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JAVA反射机制的应用(2)

阅读更多

JAVA反射机制的应用(2)

Spring中的AOP(面向切面的编程)

在MVC中,业务层对象扮演了相当重要的作用,它的方法代表了核心业务逻辑,但是可能还有一些附加的操作,比如写日志等其它操作也会包含在其中,那么可能会带来几个问题:

  • 冗余代码的出现
  • 破坏了面向对象的思想。各个方法应该各司其职,只做它应该做的那一部分工作,而这里这些辅助操作的引入会破坏这个特性。

这里我们把这些附加操作(比如写日志操作)看成一个切面,并且把它从业务方法中抽离出来,然后把它植入到各个业务方法中,这样维护这些辅助操作是相当容易了,而且也不会出现冗余代码。那么这种思想怎么实现呢?

这里把上面提到的业务对象称为目标对象,再引入一个委托对象(下面会讲到两种委托对象),我们不直接对目标对象进行操作,而是对委托对象进行方法调用,在委托对象的方法中可以完成切面操作,接着再把方法调用转交到相应的目标对象上。

 

AOP的两种实现方式:

(1)CgLib 运行时代码增强工具,它是一个第三方的工具,运行时使用cglib可以 动态地给一个类生成一个子类 ,并使用子类对象作为父类对象的委托。 CGLIB包对代理那些没有实现接口的类非常有用。 它是通过动态的生成一个子类去覆盖所要代理类的不是final的方法,并设置好callback ,setCallback的参数是一个MethodInterceptor接口的实现类实例,则原有类的每个方法调用就会转变成调用用户在 MethodInterceptor 自定义的拦截方法(intercept)。 在这个拦截方法中,我们可以在intercept方法中首先处理我们要辅助的逻辑,完了之后再使用 proxy.invokeSuper(o, os)来调用父类中的相应 方法来处理

步骤:首先需要一个cglib的jar包,并配置到classPath中,cglib有一个核心接口:MethodInterceptor接口,我们需要创建类来实现这个接口,并实现其中的方法:

public Object intercept(Object o, Method m, Object[] os, MethodProxy proxy)

该方法中我们可以定义一些特殊的逻辑,比如写日志等操作,这些操作完了之后再调用父类中的相关方法。

除此之外,在该类中还要创建一个Enhancer对象,参考以下内容

用Enhancer生成一个原有类的子类,并且设置好callback , 则 原有类的每个方法调用都会转成调用实现了MethodInterceptor接口的proxy的intercept() 函数       public Object intercept(Object o,Method method,Object[] args,MethodProxy proxy)  

     在intercept()函数里,你可以执行Object result=proxy.invokeSuper(o,args)来执行原有函数,在执行前后加入自己的东西,改变它的参数,也可以瞒天过海,完全干别 的。说白了,就是AOP中的around advice。

public class TestCglibProxy {
	public static void main(String[] args) {
		AProxy ap=new AProxy();
		A a=(A)ap.getProxy(A.class);   //利用cglib创建A类的子类对象(代理对象)
  		a.method1();   //调用父对象的method1方法时会会调用代理对象的intercept方法
                a.method2();
	}
}

class A{
	public void method1(){
		System.out.println("A method1");
	}
	public void method2(){
		System.out.println("A method2");
	}
}

class AProxy implements MethodInterceptor{
	private Logger log=Logger.getLogger("A");
	private Enhancer en=new Enhancer();
	public Object getProxy(Class c){   //c是所要代理的父类的Class对象
                en.setCallback(this);  //表示调用父对象的方法时,回调当前对象的intercept方法
    		en.setSuperclass(c);  //设置父类对象
 		return en.create();    //创建一个代理类的实例
 }
	public Object intercept(Object o, Method m, Object[] os, MethodProxy proxy) throws Throwable {
		log.info("invoke method "+m.getName());
		Object result=proxy.invokeSuper(o, os);
		return result;
	}
} 


(2)动态代理方式

目标类T和代理类P都实现同样一个接口I 其中 P类对象中包含了一个T类的对象 ,在P和T实现接口I的同一个方法M时,可以在P中的M中调用T的M 方法 同时在调用T的M之前或者之后进行一些自定义的操作。

一个简单的代理模式实现

Interface I{

   void method1();

}

class T implements I{

  public void method() {

   ...

}

}

class P implements I {

private T t;

public P(T t) {

this.t = t;

}

public void methid() {

//do something

t.method();

//do something

}

}

上面的代码相信大家都能看懂 ,这就是一个代理模式的简单实现。

下面来介绍一下JAVA中已有的动态代理框架,三个关键类:Proxy,InvocationHandler,Method对象,首先我们需要创建目标类动态代理对象,怎么创建呢?调用:

 

newProxyInstance ( ClassLoader loader, Class <?>[] interfaces, InvocationHandler h)

前面讲过了代理类和目标类实现共同的接口,因此需要将目标类所实现的接口(这里是一个Class数组)传给Proxy,除此之外还需要传 递目标类的类加载器和InvocationHandler实例,类加载器当然是用来加载生成的代理类的class文件,而这里的 InvocationHandler是什么呢?顾名思义,调用处理器,当对代理类调用相应的方法时(这里的方法其实是我们想对目标类调用的),该方法调用 会被拦截,并回调InvocationHandler实现类的invoke方法,我们来简单看看invoke方法:

 

invoke ( Object  proxy, Method  method, Object [] args)

invoke方法中又包含了三个参数,第一个是代理对象proxy,第二个是Method对象,第三个是一个Object数组,这里简单介绍下这三个参 数:proxy对象大家应该都知道了,即代理对象 上面利用Proxy的静态newProxyInstance方法创建的 ;method对象,即方法对象,这里的方法对象是什么呢?刚才说到了对代理对象调用方法时会被拦截,而这里的method就是被拦截的方法对象 最后一个是args,相信大家对这个变量不会陌生,这里表示的是对代理对象调用方法时所传递的参数,参数可能为一个,两个或者多个,当然也可能没有,因此这里用一个数组表示。

肯定有人会问我在这个方法里写什么呢?爱写什么你写什么,呵呵,开个玩笑。 按照常理来说,这里面肯定会调用目标对象的method方法了,不然这代理还有什么意义!!!那怎么调用呢?相信有java反射基础的人大家应该都知道吧,不知道或者不熟练就查查API:

 

invoke ( Object obj, Object ... args)

第 一个对象是目标对象,第二个是参数数组,这里又涉及问题,怎么把目标对象传递到这儿呢?我这里介绍两种方法,其实大家应该都能想到,在定义 InvocationHandler实现类时,把目标类作为它的成员变量,通过构造函数把目标对象赋值给它,那么在invoke方法中当然就可以直接使用 了;另外一种更简单的方法,InvocationHandler的实例使用匿名内部类创建:

new InvocationHandler() {

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

       ...

      method,invoke(target, args);

      ...

    }

}

这里的target可以来自方法参数,但一定要是final的。

public class TestProxy {
	public static void main(String[] args){
		/*
		I target=new Target();
		I proxy=(I)ProxyFactory.getProxy(target);
		proxy.method();
		*/
		List list=new ArrayList();
		List listProxy=(List)ProxyFactory.getProxy(list);
		listProxy.add("abc");
		listProxy.add("def");
		listProxy.add(0,"123");
		listProxy.remove(1);
		listProxy.size();
		for(Object o:list){
			System.out.println(o);
		}
	}
}
interface I{
	void method();
}
class Target implements I{
	public void method(){
		System.out.println("Target method");
	}
}
class TargetProxy implements I{
	I target;
	public TargetProxy(I target){
		this.target=target;
	}
	public void method(){
		System.out.println("do sth in proxy");
		target.method();
	}
}
class ProxyFactory{
	public static Object getProxy(final Object target){
		Class c=target.getClass();
		ClassLoader loader=c.getClassLoader();
		Class[] is=c.getInterfaces();
		return Proxy.newProxyInstance(loader,is,new InvocationHandler(){
			public Object invoke(Object proxy, Method m, Object[] os) throws Throwable {
				System.out.println("invoke "+m.getName());
				return m.invoke(target, os);
			}
		});
	}
}
 

以上内容部分来自:http://nucchenyibin.iteye.com/blog/667733

                           http://www.zx2010.com/program/java-cglib-proxy.asp

 

0
1
分享到:
评论

相关推荐

    JAVA反射机制应用

    JAVA反射机制应用 JAVA反射机制是JAVA语言中的一种动态机制,它能够在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法。这种动态获取的信息以及动态...

    java反射机制应用

    ### Java反射机制应用详解 #### 一、Java反射机制简介 Java反射机制是Java语言提供的一种能在运行时分析类信息并动态操作对象的功能。通过反射,我们可以在程序运行期间获取类的信息(如类名、方法名等),创建...

    JAVA 反射机制应用

    Java反射机制是Java语言提供的一种强大功能,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类是java.lang.Class,它代表了运行时的类信息。通过Class对象,我们...

    java面试题--反射机制

    通过本文,我们将深入探讨Java反射机制的核心概念、基本原理及其应用场景。 #### 二、Java反射机制简介 Java反射机制允许程序在运行时获取类的信息,这使得Java具有了一定程度上的动态性。具体来说,Java反射机制...

    java的反射机制及其实际应用

    ### Java的反射机制及其实际应用 #### 一、引言 ...总之,Java反射机制是一项强大的工具,它能够在运行时动态地获取和操作类的信息。然而,应该谨慎使用反射,避免滥用造成不必要的性能损失或安全风险。

    Java反射机制 Java反射机制

    #### 三、Java反射机制的核心概念与应用 1. **核心概念** - **Class对象**:每个加载到Java虚拟机中的类都会对应一个Class对象,该对象包含了类的完整信息。 - **Method对象**:表示类中的方法,通过它可以获取...

    JAVA反射机制及应用例子

    JAVA反射机制及应用例子.。。Reflection API

    java反射机制详解与应用.pdf

    * Struts2 框架:使用 Java 反射机制来实现动态加载类别和实现依赖注入。 * Spring 框架:使用 Java 反射机制来实现依赖注入和面向方面编程。 * Hibernate 框架:使用 Java 反射机制来实现动态代理和实现依赖注入。 ...

    Java反射机制总结

    ### Java反射机制总结 #### 反射的概念与起源 反射的概念最早由Smith于1982年提出,指的是程序能够访问、检测并修改其自身状态或行为的能力。这一概念的提出迅速引起了计算机科学领域的广泛关注,并在之后的研究中...

    反射实例-JAVA反射机制

    ### 反射实例—JAVA反射机制 #### 一、反射概念及原理 ...总结而言,Java反射机制是构建灵活、可扩展应用程序的强大工具。然而,在使用反射时,开发者应当权衡其带来的好处和潜在的风险,确保合理有效地利用这一特性。

    java 反射机制详解

    Java 反射机制是 Java 语言中的一个重要特性,它允许程序在运行时动态地获取类的信息(如类名、属性、方法等)并调用对象的方法,甚至修改对象的状态。这一机制极大地增强了 Java 程序的灵活性和可扩展性,尤其是在...

    Java反射机制的实现_Reflection

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部信息。通过Java反射机制,开发者可以在不知道具体类名的情况下创建对象,调用方法,访问和修改私有成员变量,以及...

    候捷谈Java反射机制

    Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时获取和操作任何已知名称的类的内部信息。这一机制使得Java具备了一定的动态性,虽然在传统的分类中Java被视为静态类型语言。通过反射,开发者可以在...

    java 反射机制例子

    ### Java反射机制详解 #### 一、反射的基本概念与历史背景 反射的概念最早由Smith在1982年提出,其核心思想是程序有能力访问、检测甚至...对于初学者而言,了解并掌握Java反射机制的基本原理和应用场景是非常有益的。

    Java反射机制经典案例

    Java反射机制是Java编程语言中的一个强大...通过以上介绍,我们了解了Java反射机制的基本概念、使用方法、应用场景以及需要注意的问题。在实际编程中,合理利用反射可以提高代码的灵活性,但同时也需注意其潜在的风险。

    Java反射机制Demo

    ### Java反射机制详解 #### 一、什么是Java反射机制? Java反射机制是在运行状态中,对于任意一个类,都...以上是关于Java反射机制的基本概念、用法和示例解析,希望能帮助你更好地理解和应用这一重要的Java特性。

    Java反射机制学习(二)

    这篇博文"Java反射机制学习(二)"可能深入探讨了如何利用反射进行动态类型处理、访问私有成员以及创建对象等核心概念。在这里,我们将详细讨论Java反射的基本用法及其在实际开发中的应用。 1. **什么是反射**: ...

    Java 反射机制 代码的实例

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部结构。通过反射,开发者可以动态地获取类的信息并调用其方法,创建对象,访问私有成员,甚至改变类的行为。在深入...

    北大青鸟java反射机制

    此外,Java反射机制也广泛应用于注解处理。`Annotation`接口代表了类、方法、字段等上的注解。我们可以使用`isAnnotationPresent(Class&lt;? extends Annotation&gt; annotationClass)`检查是否存在特定注解,`...

Global site tag (gtag.js) - Google Analytics