好记性不如烂笔头47-java拦截器-用CGLib实现动态代理(2)

动态代理技术是整个java技术系统中非常重要的一环,它是我们能够深入学习java框架的基础,是深入了解Spring等框架时要掌握的基础知识之一。

Java中自带的动态代理的类必须要实现一个接口,也就是说只能对该类所实现接口中定义的方法进行代理,这在实际编程中具有一定的局限性,而且使用反射的效率也并不是很高。于是CGLIB就诞生了。

使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,理论上比使用Java反射效率要高。

1、 CGLib动态代理的概念

举例:歌星或者明星都有一个自己的经纪人,这个经纪人就是他们的代理人,当我们需要找明星表演时,不能直接找到该明星,只能是找明星的代理人。比如王宝强在现实生活中非常有名,会唱歌,会跳舞,会拍戏。王宝强在没有出名之前,在他们村种地的时候,我们可以直接找他唱歌,跳舞,拍戏,王宝强出名之后,他找了一个经纪人,这个经纪人就是王宝强的代理人(代理),当我们需要找王宝强表演时,不能直接找到王宝强了(王宝强说,你找我的代理人吧!),因此王宝强这个代理人存在的价值就是拦截我们对王宝强的直接访问!

原来的代理人要求和王宝强一样会唱歌跳舞,但是这样的代理人不多呀,实在找不到这样的代理人,那么就降低要求把,你要找王宝强,我就把他找出来给你好了。

王宝强(真实业务对象)会唱歌,会跳舞,会拍戏,我们现在不能直接找他唱歌,跳舞,拍戏了,只能找他的代理人(代理对象)唱歌,跳舞,拍戏。

2、 一些前提条件

需要额外导入cglib-2.2.0.jar

3、 Java中利用CGLib实现目标对象类(具体实施对象)

package com.CGLib;
/**
 * 王宝强是一个演员,他会唱歌和跳舞.
 * 这里没有实现接口
 * @author 范芳铭
 */
public class WangBaoQiang{
    private String name ;
    public WangBaoQiang(){
        this.name = "王宝强";
    }
    public String sing(String name){
        System.out.println(this.getName() + "开始唱"+name+"歌!!");
        return "歌唱完了,谢谢大家!";
    }

    public String dance(String name){
        System.out.println(this.getName() +  "开始跳"+name+"舞!!");
        return "舞跳完了,谢谢大家!";
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

}

4、 JAVA中利用CGLib生成代理对象的代理类

package com.CGLib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
 * 演员的经纪人,他不会唱歌和跳舞,但是经纪人能找到会唱歌跳舞的人
 * @author 范芳铭
 */
public class ActorJingJiRen implements MethodInterceptor{
    public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable {
        System.out.println("CGLIB Before:"+method);
        System.out.println("我是他的经纪人,有事情先找我!");
        Object object=proxy.invokeSuper(obj, arg);
        System.out.println("CGLIB After: 结束。");
        return object;
    }

    public WangBaoQiang getProxy(){
         Enhancer enhancer = new Enhancer();
         enhancer.setSuperclass(WangBaoQiang.class);
         enhancer.setCallback(new ActorJingJiRen());
         WangBaoQiang object=(WangBaoQiang)enhancer.create();
         return object;
    }
}

5、 调用动态代理的测试类

package com.CGLib;

/**
 * 测试类,找到经纪人提出唱歌跳舞的要求就行
 *
 * @author 范芳铭
 */
public class ProxyTest {
    public static void main(String[] args) {
        // 首先找到经纪人
        ActorJingJiRen proxy = new ActorJingJiRen();
        // 通过经纪人获得相关演员(代理对象)
        WangBaoQiang p = proxy.getProxy();
        // 让演员唱歌
        String retValue = p.sing("天下无贼");
        System.out.println(retValue);
        // 让演员跳舞
        String value = p.dance("凤凰传奇");
        System.out.println(value);
    }
}

6、 运行结果

CGLIB Before:public java.lang.String com.CGLib.WangBaoQiang.sing(java.lang.String)

我是他的经纪人,有事情先找我!

CGLIB Before:public java.lang.String com.CGLib.WangBaoQiang.getName()

我是他的经纪人,有事情先找我!

CGLIB After: 结束。

王宝强开始唱天下无贼歌!!

CGLIB After: 结束。

歌唱完了,谢谢大家!

CGLIB Before:public java.lang.String com.CGLib.WangBaoQiang.dance(java.lang.String)

我是他的经纪人,有事情先找我!

CGLIB Before:public java.lang.String com.CGLib.WangBaoQiang.getName()

我是他的经纪人,有事情先找我!

CGLIB After: 结束。

王宝强开始跳凤凰传奇舞!!

CGLIB After: 结束。

舞跳完了,谢谢大家!

补充说明:在执行一个动作之前,有2个CGLIB Before被执行,是因为还有一个内部动作被执行(getName()),因为所有的动作都会被拦截,因此这里有2个。

时间: 2024-08-27 20:15:53

好记性不如烂笔头47-java拦截器-用CGLib实现动态代理(2)的相关文章

好记性不如烂笔头48-java拦截器-JDK自带动态代理和CGLIB效率比较(3)

Java中自带的动态代理的类必须要实现一个接口,而且据说使用反射的效率也并不是很高.于是CGLIB就诞生了. 使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,理论上比使用Java反射效率要高. 那么我们测试下,这个运行的效率如何. 1. 测试的准备情况 准备1:好记性不如烂笔头46-java拦截器-彻底理解动态代理的概念(1) http://blog.csdn.net/ffm83/article/details/

从“好记性不如烂笔头”“记问之学不足为人师”到“一事不知是我之耻”

“好记性不如烂笔头”错在一笔记容易丢失,二考验随时发生而笔记常不随身.因此记到大脑里最可靠. “记问之学不足为人师”错在低估记忆力的作用而盲目推崇推理逻辑,这像不打地基盖楼,要不不牢靠要不会垮. “一事不知是我之耻”这是一种认真积极的态度,这样才能应付随时出现的挑战. 2017年3月12日00:34:22

Python学习中的随笔,好记性不如烂笔头

本文 为博主看了 vamei 的blog 写下的随笔 . 致敬Vamei 1.type()   可以显示参数的类型 如 : a=12   type(a) 为 int 2.python的基本类型 为 int float bool string   如 int :  i=1   ,   float :  f=12.5  ,  bool : b= True  or  Flase , string :  s='Hello , word !' 使用前无需声明类型  即 动态类型 3.1序列有 tuple

好记性不如烂笔头

今天再次深刻领悟这个技能.tm竟然忘记博客园的用户名了.... 好记性不如烂笔头,布布扣,bubuko.com

java 拦截器、过滤器、监听器

转自:http://www.cnblogs.com/wangyuyu/archive/2013/07/02/3167354.html 一.理解Struts2拦截器 1. Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现. 2. 拦截器栈(Interceptor Stack).Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链.在访问被拦截的方法或字段时,Struts2拦截器链中的拦截

开篇记(好记性不如烂笔头)

入园两年零三个月,我居然没有一点东西记载下来实在是不应该. 爷爷曾经告诉过我,好记性不如烂笔头.他告诉了我最鲜明的例子.爷爷的脑子一直很好用,记性也是比常人好上一些,当然这也直接导致了爷爷的性格很是高傲.爷爷年轻的时候喜欢舞文弄墨什么的,所以呢每逢人家红白喜事的时候都会去人家及里面瞅上一眼,看看人家送上的喜联或者挽联.有此爱好的还有我的一个另一个宋爷爷,他们经常约好一起的.爷爷老是自信于强悍的记忆能力,每次都是记在脑子中,而宋爷爷却每次都将那些很好的对联记载一个小本子上面.如今爷爷年纪越来越大,

java 拦截器

一.前言 这是一篇关于 java 拦截器的文章,是我的写 java  web 所遇见的问题.当我们写好一个网站,必须要通过登陆页面次啊可以进入这个系统.那么我们就得写个 java 拦截器,如果是通过登录进入系统的用户,那么这样的用户就可以访问任何一个文件或者任何的 jsp 页面.如果非登录界面想进入系统,或者想搞事情的用户,我们是不允许他进入我们的系统的.这就是拦截器的功能. 参考的实例:时间辜负了谁的博客 二.代码实现 实现这个功能,我们需要写一个类,让这个类继承 Fliter 这个类.这里强

Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,拦截器Ajax请求

Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,拦截器Ajax请求 java 判断请求是不是ajax请求,Java判断是否为ajax请求 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ?Copyright 蕃薯耀 2017年8月10日 http://www.cnblogs.com/

好记性不如烂笔头89-spring3学习(10)-spring3常用schema(持续整理)

Spring3有很多的schema,这些schema对应很多不同的功能.使用这些常用的schema,能让我们避免重复发明轮子,提高我们的开发效率. 我以为这是一个很常见的信息,到网上随便整理下就能完成,可能用的关键词不对,怎么找也没有找到相对比较全面的. 正所谓,好记性不如烂笔头,自己动手把自己能收集到的整理下来,以后需要找资料也能方便点. spring-beans-3.0.xsd 用途:spring3最主要的schema,用于配置bean 命名空间: http://www.springfram