- 浏览: 189018 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
netwelfare:
这篇文章关于jsessionid讲解的不错。关于jsessio ...
关于JSessionID【转】 -
ITcms:
Activity直接执行了onCreate方法的那部分,我觉得 ...
Android之Activity学习 -
tinygroup:
Sorry发错了。
蛇形矩阵的java实现 -
tinygroup:
public static int[][] spira ...
蛇形矩阵的java实现 -
laitao:
[*]引用pulic djs
Servlet的生命周期
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
发表评论
-
Java序列化机制和原理【转】
2011-05-18 09:14 1141序列化的必要性 Java中,一切都是对象,在分布式环境中经 ... -
JAVA反射机制的简单应用(1)
2010-12-06 13:15 1436JAVA反射机制的简单应用(1) Spring中的IOC ... -
java反射学习笔记
2010-12-05 10:21 1559java反射作用: 1、自省:通过对象自身获得类结构,继 ... -
Java反射笔记(2)
2010-12-02 09:46 1735java.lang.array提供了动态 ... -
Java反射笔记(1)
2010-12-01 10:54 1139感谢张龙老师的视频:http://www.verycd.com ... -
连接池的基本工作原理及简单实现
2010-11-24 21:25 918连接池的基本工 ... -
Java 继承与组合的区别
2010-11-22 10:36 7991根据网络上大家对 ... -
蛇形矩阵的java实现
2010-11-10 22:22 7890题目: 计算并输出 nXn ... -
两个矩阵的乘积的java实现
2010-11-10 16:23 8335题目: 计算两个矩阵 A、B 的乘积矩阵 C。 ... -
螺旋数组的java实现
2010-11-10 15:26 2099螺旋数组 要求:存储和输出nXm的螺旋数组,其中n和m为 ... -
统计一个整数中出现次数最多最大的数字
2010-11-10 09:31 6547要求: 统计一个整数中出现最多的数字。如果数字个数 ... -
“百元买百鸡问题”之一重循环实现
2010-11-09 10:06 3710问题描述: 每只母鸡 3 元,每只公鸡 4 元,每只小鸡 0 ... -
[转]欧几里得算法(辗转相除法)求最大公约数
2010-11-08 22:52 2870欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数 ... -
[转]深入理解自增自减运算符a=a++和a=++a
2010-11-07 23:04 3237更深入地理解自增自减运算符 首先贴一个非常简洁却 ... -
[转]java中char,byte,short的移位操作
2010-11-07 22:38 4746在Think in Java中有这么一段话“对c ... -
笔试题之以单词为最小单位翻转字符串
2010-11-06 15:39 2394最近做了几个公司 ... -
java解惑之无穷大和NaN
2010-11-01 10:12 17851、i == i + 1 一个数字永远不会等于它自己加1 ... -
java 死锁及解决
2010-10-31 21:28 1126Java线程死锁如何避免 ... -
深入Java关键字null
2010-10-31 14:20 839深入Java关键字null ... -
对java中equals和hashCode函数的一些理解2(转)
2010-10-31 11:24 1052一致性 即如果两个对象相等的话,那么它们必须始终保持相等,除非 ...
相关推荐
JAVA反射机制应用 JAVA反射机制是JAVA语言中的一种动态机制,它能够在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法。这种动态获取的信息以及动态...
### Java反射机制应用详解 #### 一、Java反射机制简介 Java反射机制是Java语言提供的一种能在运行时分析类信息并动态操作对象的功能。通过反射,我们可以在程序运行期间获取类的信息(如类名、方法名等),创建...
Java反射机制是Java语言提供的一种强大功能,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类是java.lang.Class,它代表了运行时的类信息。通过Class对象,我们...
通过本文,我们将深入探讨Java反射机制的核心概念、基本原理及其应用场景。 #### 二、Java反射机制简介 Java反射机制允许程序在运行时获取类的信息,这使得Java具有了一定程度上的动态性。具体来说,Java反射机制...
### Java的反射机制及其实际应用 #### 一、引言 ...总之,Java反射机制是一项强大的工具,它能够在运行时动态地获取和操作类的信息。然而,应该谨慎使用反射,避免滥用造成不必要的性能损失或安全风险。
#### 三、Java反射机制的核心概念与应用 1. **核心概念** - **Class对象**:每个加载到Java虚拟机中的类都会对应一个Class对象,该对象包含了类的完整信息。 - **Method对象**:表示类中的方法,通过它可以获取...
JAVA反射机制及应用例子.。。Reflection API
* Struts2 框架:使用 Java 反射机制来实现动态加载类别和实现依赖注入。 * Spring 框架:使用 Java 反射机制来实现依赖注入和面向方面编程。 * Hibernate 框架:使用 Java 反射机制来实现动态代理和实现依赖注入。 ...
### Java反射机制总结 #### 反射的概念与起源 反射的概念最早由Smith于1982年提出,指的是程序能够访问、检测并修改其自身状态或行为的能力。这一概念的提出迅速引起了计算机科学领域的广泛关注,并在之后的研究中...
### 反射实例—JAVA反射机制 #### 一、反射概念及原理 ...总结而言,Java反射机制是构建灵活、可扩展应用程序的强大工具。然而,在使用反射时,开发者应当权衡其带来的好处和潜在的风险,确保合理有效地利用这一特性。
Java 反射机制是 Java 语言中的一个重要特性,它允许程序在运行时动态地获取类的信息(如类名、属性、方法等)并调用对象的方法,甚至修改对象的状态。这一机制极大地增强了 Java 程序的灵活性和可扩展性,尤其是在...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部信息。通过Java反射机制,开发者可以在不知道具体类名的情况下创建对象,调用方法,访问和修改私有成员变量,以及...
Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时获取和操作任何已知名称的类的内部信息。这一机制使得Java具备了一定的动态性,虽然在传统的分类中Java被视为静态类型语言。通过反射,开发者可以在...
### Java反射机制详解 #### 一、反射的基本概念与历史背景 反射的概念最早由Smith在1982年提出,其核心思想是程序有能力访问、检测甚至...对于初学者而言,了解并掌握Java反射机制的基本原理和应用场景是非常有益的。
Java反射机制是Java编程语言中的一个强大...通过以上介绍,我们了解了Java反射机制的基本概念、使用方法、应用场景以及需要注意的问题。在实际编程中,合理利用反射可以提高代码的灵活性,但同时也需注意其潜在的风险。
### Java反射机制详解 #### 一、什么是Java反射机制? Java反射机制是在运行状态中,对于任意一个类,都...以上是关于Java反射机制的基本概念、用法和示例解析,希望能帮助你更好地理解和应用这一重要的Java特性。
这篇博文"Java反射机制学习(二)"可能深入探讨了如何利用反射进行动态类型处理、访问私有成员以及创建对象等核心概念。在这里,我们将详细讨论Java反射的基本用法及其在实际开发中的应用。 1. **什么是反射**: ...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部结构。通过反射,开发者可以动态地获取类的信息并调用其方法,创建对象,访问私有成员,甚至改变类的行为。在深入...
此外,Java反射机制也广泛应用于注解处理。`Annotation`接口代表了类、方法、字段等上的注解。我们可以使用`isAnnotationPresent(Class<? extends Annotation> annotationClass)`检查是否存在特定注解,`...