记性不如烂笔头46-java拦截器-彻底理解动态代理的概念(1)

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

1、 JAVA中代理的概念

动态代理技术就是用来产生一个对象的代理对象的。直接说好像也很迷糊,好像用不上的样子。

(下面的例子部分来自互联网)

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

这个例子和我们在开发中是一样的,我们在开发中之所以要产生一个对象的代理对象,主要用于拦截对真实业务对象的访问。

那么代理对象应该具有什么方法呢?代理对象应该具有和目标对象相同的方法。

1、代理对象存在的价值主要用于拦截对真实业务对象的访问。

2、代理对象应该具有和目标对象(真实业务对象)相同的方法。

王宝强(真实业务对象)会唱歌,会跳舞,会拍戏,我们现在不能直接找他唱歌,跳舞,拍戏了,只能找他的代理人(代理对象)唱歌,跳舞,拍戏,一个人要想成为刘德华的王宝强,那么他必须看起来具有和王宝强一样的行为(会唱歌,会跳舞,会拍戏),王宝强有什么方法,他(代理人)就要有什么方法,我们找王宝强的代理人唱歌,跳舞,拍戏,但是代理人不是真的懂得唱歌,跳舞,拍戏的,真正懂得唱歌,跳舞,拍戏的是王宝强,在现实中的例子就是我们要找王宝强唱歌,跳舞,拍戏,那么只能先找他的经纪人,交钱给他的经纪人,然后经纪人再让王宝强去唱歌,跳舞,拍戏。

2、 JAVA中实现动态代理的类和方法

java在JDK1.5之后提供了一个”java.lang.reflect.Proxy”类,通过”Proxy”类提供的一个newProxyInstance方法用来创建一个对象的代理对象:

static Object newProxyInstance(ClassLoader loader, Class

3、 定义对象的行为接口

在java中规定,要想产生一个对象的代理对象,那么这个对象必须要有一个接口,所以我们第一步就是设计这个对象的接口,在接口中定义这个对象所具有的行为(方法)。

package com.proxy;
/**
 * 一个演员对象的接口,需要会唱歌和跳舞
 * @author 范芳铭
 */
public interface  Actor {
     String sing(String name);
     String dance(String name);
}

4、 定义目标对象类(具体实施对象)

package com.proxy;
/**
 * 王宝强是一个演员,他会唱歌和跳舞
 * @author 范芳铭
 */
public class WangBaoQiang implements Actor{
    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;
    }

}

5、 定义生成代理对象的代理类

package com.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * 演员的经纪人,他不会唱歌和跳舞,但是经纪人能找到会唱歌跳舞的人
 * @author 范芳铭
 */
public class ActorJingJiRen {
    // 设计一个类变量记住代理类要代理的目标对象
    private Actor actor = new WangBaoQiang();

    // 通过经纪人,返回王宝强的对象
    public Actor getProxy() {
        // 使用Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
        // InvocationHandler h)返回某个对象的代理对象
        return (Actor) Proxy.newProxyInstance(ActorJingJiRen.class
                .getClassLoader(), actor.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * InvocationHandler接口只定义了一个invoke方法,因此对于这样的接口,
                     * 我们不用单独去定义一个类来实现该接口, 而是直接使用一个匿名内部类来实现该接口,new
                     * InvocationHandler() {}就是针对InvocationHandler接口的匿名实现类
                     *
                     * 在invoke方法编码指定返回的代理对象干的工作 proxy : 把代理对象自己传递进来
                     * method:把代理对象当前调用的方法传递进来 args:把方法参数传递进来
                     * 因此我们可以在invoke方法中使用method.getName()就可以知道当前调用的是代理对象的哪个方法
                     */
                    @Override
                    public Object invoke(Object proxy, Method method,
                            Object[] args) throws Throwable {
                        if (method.getName().equals("sing")) {
                            System.out.println("我是他的经纪人,有事情先找我!");
                            //代理对象调用真实目标对象的sing方法去处理用户请求
                            return method.invoke(actor, args);
                        }
                        if (method.getName().equals("dance")) {
                            //代理对象调用真实目标对象的dance方法去处理用户请求
                            System.out.println("我是他的经纪人,有事情先找我!");
                            return method.invoke(actor, args);
                        }
                        return null;
                    }
                });
    }
}

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

package com.proxy;

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

7、 运行结果

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

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

歌唱完了,谢谢大家!

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

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

舞跳完了,谢谢大家!

时间: 2024-10-12 12:28:37

记性不如烂笔头46-java拦截器-彻底理解动态代理的概念(1)的相关文章

拦截器(由JDK动态代理实现的拦截器)

要实现拦截器,首先我们需要定义几个类和接口 package com.xiawei.reflect.interceptor; public interface JavaBenDao { public void look();} ================================================== package com.xiawei.reflect.interceptor; public class JavaBenDaoImpl implements JavaBen

java拦截器(Interceptor)学习笔记

1,拦截器的概念    java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了一种可以提取Action中可重用部分代码的方式.在AOP中,拦截器用于在某个方法或者字段被访问之前,进行拦截然后再之前或者之后加入某些操作.目前,我们需要掌握的主要是Spring的拦截器,Struts2的拦截器不用深究,知道即可. 过滤器.监听器.拦截器差异图2,拦截器的原理    大部分时候,拦截

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/

JAVA拦截器VS过滤器

拦截器的实现原理: 拦截器方法是通过代理的方式来调用的.Struts 2的拦截器实现相对简单.当请求到达Struts 2的ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list)形成一个拦截器链,最后一个一个地调用列表中的拦截器. Servlet过滤器的基本原理         在Servlet作为过滤器使用时,它可以对客户的请求进行处理.处理完成后,它会交给下一个过滤器处理,这样,客户的请求在过滤链里逐个处理,直到请

Java的反射机制和动态代理

介绍Java注解的时候,多次提到了Java的反射API.与javax.lang.model不同的是,通过反射API可以获取程序在运行时刻的内部结构.反射API中提供的动态代理也是非常强大的功能,可以原生实现AOP中 的方法拦截功能.正如英文单词reflection的含义一样,使用反射API的时候就好像在看一个Java类在水中的倒影一样.知道了Java类的内部 结构之后,就可以与它进行交互,包括创建新的对象和调用对象中的方法等.这种交互方式与直接在源代码中使用的效果是相同的,但是又额外提供了运行时

java开发必学知识:动态代理

目录 1. 引言 2. 代理模式及静态代理 2.1 代理模式说明 2.2 静态代理 2.3 静态代理局限性 3. 动态代理 3.1 JAVA反射机制 3.2 JDK动态代理 3.2.1 JDK动态代理 3.2.2 JDK动态代理与限制 3.4 CGLIB动态代理 4. 动态代理在Spring的应用:AOP 4.1 AOP 概念 4.2 AOP编程 4.2.1 引入aop依赖 4.2.2 定义切面.切点与通知 5. 总结 参考资料 往期文章 一句话概括:java动态代理通过反射机制,可在不修改原代

java反射机制中的动态代理

java反射机制中的动态代理 动态代理模式及其使用 步骤1:定义一个接口 //接口 interface Subject{ void action(); } 步骤2:定义一个接口的实现类,也就是被代理类 //被代理类 class RealSubject implements Subject { @Override public void action() { System.out.println("我是被代理类,请执行我"); } } 步骤3:定义一个实现InvocationHandle