Java 代理模式有如下几种实现方式:

  1.静态代理。    

2.JDK动态代理。

3.CGLIB动态代理。

示例,有一个打招呼的接口。分别有两个实现,说hello,和握手。代码如下。

接口:

public interface Greeting {

    public void doGreet();
}

实现类:

public class SayHello implements Greeting {

    @Override
public void doGreet() {
System.out.println("Greeting by say 'hello' .");
} }
public class ShakeHands implements Greeting {

    @Override
public void doGreet() {
System.out.println("Greeting by shake others's hands .");
} }
public class KissHello  {

    public void doGreet() {
System.out.println("Greeting by kiss . ");
} }

在不改变代码的情况下,想在执行目标方法 前后 做一些其他操作。则可以通过代理方式来实现。

1.静态代理。需要创建代理类。代理类实现了和目标类一样的接口,代理类接收目标类对象,并在实现方法中调用目标类的实现方法前后做手脚。如下:

public class GreetStaticProxy implements Greeting {

    private Greeting hello;//被代理对象
public GreetStaticProxy(Greeting hello){
this.hello=hello;
} @Override
public void doGreet() {
before();//执行其他操作
this.hello.doGreet();//调用目标方法
after();//执行其他操作
} public void before(){
System.out.println("[StaticProxy] Come to someone.");
}
public void after(){
System.out.println("[StaticProxy] Back to his own corner");
}
}

测试调用:

public class Main {

    public static void main(String[] args) {
Greeting hello=new SayHello();
Greeting shakeHands=new ShakeHands(); //静态代理
GreetStaticProxy staticHelloProxy=new GreetStaticProxy(hello);
staticHelloProxy.doGreet();
System.out.println();
GreetStaticProxy shakeHandsProxy=new GreetStaticProxy(shakeHands);
shakeHandsProxy.doGreet();
}
运行结果:
[StaticProxy] Come to someone.
Greeting by say 'hello' .
[StaticProxy] Back to his own corner [StaticProxy] Come to someone.
Greeting by shake others's hands .
[StaticProxy] Back to his own corner

这个方式有弊端,如果有N个接口的实现类需要被代理,则需要创建N个代理类。

2.JDK动态代理

创建代理类,如下:

public class JdkProxy implements InvocationHandler {

    private Object target;

    public JdkProxy(Object obj){
this.target=obj;
} @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable { Object result=null;
before();
result=method.invoke(target, args);
after();
return result;
} public void before(){
System.out.println("[JdkProxy] Come to someone.");
}
public void after(){
System.out.println("[JdkProxy] Back to his own corner");
}
}

测试调用:

public class Main {

    public static void main(String[] args) {
Greeting hello=new SayHello();
Greeting shakeHands=new ShakeHands(); //jdk动态代理
JdkProxy dynamicProxy=new JdkProxy(hello);
Greeting target=(Greeting) Proxy.newProxyInstance(hello.getClass().getClassLoader(),
hello.getClass().getInterfaces(), dynamicProxy);
target.doGreet();
System.out.println(); } }

这种方式和第一种方式相比,虽然不需要创建很多代理类,

但是,他依赖与“被代理的对象需要实现接口” 即:在上面给出的代码示例中,动态代理可以代理SayHello和ShakeHands,却不能代理KissHello。因为KissHello没有实现接口。

3.CGLIB动态代理。

创建代理类:

public class CglibProxy implements MethodInterceptor {

    public static CglibProxy proxy=new CglibProxy();
private CglibProxy(){} public static CglibProxy getInstance(){
return proxy;
} public <T> T getProxy(Class<T> cls){
return (T) Enhancer.create(cls, this);
} @Override
public Object intercept(Object obj, Method method, Object[] arg,
MethodProxy proxy) throws Throwable {
Object result=null;
try {
before();
result= proxy.invokeSuper(obj, arg);
after();
} catch (Exception e) {
e.printStackTrace();
}
return result;
} public void before(){
System.out.println("[cglib] Come to someone.");
}
public void after(){
System.out.println("[cglib] Back to his own corner.");
}
}

调用示例:

public class Main {

    public static void main(String[] args) {

        //cglib代理
Greeting targetProxy=CglibProxy.getInstance().getProxy(SayHello.class);
targetProxy.doGreet();
System.out.println(); CglibProxy.getInstance().getInstance().getProxy(KissHello.class).doGreet(); } }

综上,CGLIB动态代理最好,spring框架也用到了CGLIB包。

java 代理的三种实现方式的更多相关文章

  1. Java多线程的三种实现方式

    java多线程的三种实现方式 一.继承Thread类 二.实现Runnable接口 三.使用ExecutorService, Callable, Future 无论是通过继承Thread类还是实现Ru ...

  2. java的list几种实现方式的效率(ArrayList、LinkedList、Vector、Stack),以及 java时间戳的三种获取方式比较

    一.list简介 List列表类,顺序存储任何对象(顺序不变),可重复. List是继承于Collection的接口,不能实例化.实例化可以用: ArrayList(实现动态数组),查询快(随意访问或 ...

  3. Java定时器的三种实现方式

    一.普通thread /** * 普通thread * 这是最常见的,创建一个thread,然后让它在while循环里一直运行着, * 通过sleep方法来达到定时任务的效果.这样可以快速简单的实现, ...

  4. Java数组的三种打印方式

    1.数组的输出的三种方式 一维数组: 定义一个数组 int[] array = {1,2,3,4,5}; (1)传统的for循环方式 for(int i=0;i<array.length;i++ ...

  5. Java反射的三种实现方式

    Foo foo = new Foo(); 第一种:通过Object类的getClass方法 Class cla = foo.getClass(); 第二种:通过对象实例方法获取对象 Class cla ...

  6. java 多线程编程三种实现方式

    一种是继承Thread类,一种是实现Runable接口,还有一种是实现callable接口: 有博主说只有前面2种方式,我个人愚见是三种,主要详细介绍下callable的使用: 三种线程的我的个人理解 ...

  7. java集合的三种遍历方式

    import java.util.ArrayList;  import java.util.Collection;import java.util.Iterator;public class Home ...

  8. java线程的三种实现方式

    线程实现的三种种方式: 一个是继承Thread类,实现run()方法: 一个是实现Runnable接口,实现run()方法: 一个是实现Callable接口,实现call()方法:该方式和实现Runn ...

  9. Java规范的三种注释方式:

    1.单行注释 // //单行注释 2.多行注释 /* */ /* 多行 注释 */ 3.文档注释[java特有的] /** */ ◆注释内容可以被JDK提供的工具javadoc所解析,生成一套以网页文 ...

随机推荐

  1. python IDE

    提供给开发者 10 款最好的 Python IDE http://www.oschina.net/news/57468/best-python-ide-for-developers vim windo ...

  2. Openstack安全规则说明

    openstack的安全规则,主要是在网络控制器,nova-network中进行的端口限制,所以我们需要对规则进行定制. 定制通用安全组规则 通用安全组规则主要包括2个,1是支持ping的icmp协议 ...

  3. DIV 垂直 垂直水平 居中

    DIV 垂直 居中 让div居中对齐 使用margin-left:auto;margin-right:auto; 可以让你的div居中对齐.  .style{margin-left:auto;marg ...

  4. [课程设计]Scrum 2.0 多鱼点餐系统开发进度(第二阶段项目构思与任务规划)

    [课程设计]Scrum 2.0 多鱼点餐系统开发进度 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4.团队选题:餐厅到店点餐系统WEB ...

  5. SUDTOJ 3323园艺问题 (线段树)

    园艺问题 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 本巨养了一盆双色茉莉.这种花有一种特点:第i朵花在第Di天盛开,刚开时是紫色的 ...

  6. C#单独启动进程的几种方式

    本文实例讲述了C#启动进程的几种常用方法.分享给大家供大家参考.具体如下: 1.启动子进程,不等待子进程结束 private void simpleRun_Click(object sender, S ...

  7. Bootstrap_分页

    一.带页码的分页导航 <ul class="pagination"> <li><a href="#">«</a> ...

  8. Jenkins RCE2(CVE-2016-0788)EXP

    国内应该有这个EXP的不多,需要点JAVA基础,安装好maven之后,配置下就可以了,官网也给出了样例,乌云也给了分析.

  9. C#报修系统Ⅱ

    用户需求: 1.用户可以注册,可以登录. 2.需要一个报修界面,当点击“报修”按钮时,软件会把用户报修的信息保存起来,更新报修次数,同时会清空相应的文本框,软件还要要检查所有文本框是否为空,空的话给出 ...

  10. Model Binding

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...