JAVA代理方式使用示例总结

一、    代理方式概括

  Java的代理方式主要包含了静态代理,动态代理两种方式,其中,动态代理根据实现的方式不同,又可以划分为jdk动态代理和cglib动态代理.

二、    代理方式实现

1.    静态代理

  静态代理,主要包含两个实例,被代理类和代理类,两者都要实现公共的接口,能够面向接口实现,把被代理类组合到代理类中,在被代理类的本身功能上,加上代理类的自己的处理逻辑,达到增强的效果,就简单的实现了代理功能.静态代理只能事先编写好代理代码,经过统一编译后才能执行.下面简单的代码实现:

1.1建立公共的接口

package jdkcglib.dynmicagent;

/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉
*
* @author 12061799
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public interface IBookFacade { /**
*
* 功能描述: <br>
* 〈功能详细描述〉
*
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
void addBook(String name); /**
*
* 功能描述: <br>
* 〈功能详细描述〉
*
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
void deleteBook(); }

1.2建立被代理类


package jdkcglib.dynmicagent;

/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉
*
* @author 12061799
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class BookFacade implements IBookFacade { @Override
public void addBook(String name) {
System.out.println("增加图书!"+name);
} @Override
public void deleteBook() {
System.out.println("删除图书!");
}
}

1.3建立代理类

package com.lilin.maven.service;

/**
* @author lilin
*
*/
public class BookFacadeProxy implements IBookFacade {
private BookFacade bookFacade; public BookFacadeProxy(BookFacade bookFacade) {
this.bookFacade = bookFacade;
} @Override
public void addBook(String name) {
System.out.println("新增之前。。。");
bookFacade.addBook("红楼梦");
System.out.println("新增之后。。。");
} @Override
public void deleteBook() {
System.out.println("删除之前。。。");
bookFacade.deleteBook();
System.out.println("删除之后。。。");
} }

1.4建立测试类

package jdkcglib.dynmicagent;

/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉
*
* @author 12061799
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class Test { /**
* 功能描述: <br>
* 〈功能详细描述〉
*
* @param args
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/

    public static void main(String[] args) {
      BookFacadeProxy proxy = new BookFacadeProxy(new BookFacade());
      proxy.addBook("红楼梦");
      proxy.deleteBook();
    }

}

2.    动态代理---jdk动态代理(InvocationHandler 接口)

  依据java的反射机制动态生成.在运行期间可以动态生成被代理类的实例.利用反射。获取托付类的类载入器。托付类的全部接口,实例化代理类。通过反射类Proxy以及InvationHandler回调接口实现的。可是动态代理类仅仅能对该类所实现的接口中的方法进行代理。具有一定的局限性,而且反射的效率也不是非常高。下面是简单的代码实现:

2.1 建立公共接口类

package jdkcglib.dynmicagent;

/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉
*
* @author 12061799
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public interface IBookFacade { /**
*
* 功能描述: <br>
* 〈功能详细描述〉
*
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
void addBook(String name); /**
*
* 功能描述: <br>
* 〈功能详细描述〉
*
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
void deleteBook(); }

2.2 建立被代理类

package jdkcglib.dynmicagent;

/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉
*
* @author 12061799
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class BookFacade implements IBookFacade { @Override
public void addBook(String name) {
System.out.println("新增加图书!"+name);
} @Override
public void deleteBook() {
System.out.println("直接删除图书!");
} }

2.3 建立代理类

package jdkcglib.dynmicagent;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉
*
* @author 12061799
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class BookFacadeProxy implements InvocationHandler { /**
* 被代理对象
*/
private Object target; /**
*
* 功能描述: <br>
* 〈功能详细描述〉绑定被代理对象 返回代理对象
*
* @param target
* @return
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public Object bind(Object target) {
this.target = target;
// 要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)
// 返回代理对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
if (method.getName().startsWith("delete")) {
System.out.println("#####方法执行之前#####");
result = method.invoke(target, args);
System.out.println("#####方法执行之后#####");
} else {
result = method.invoke(target, args);
}
return result;
} }

2.4 建立测试类

package jdkcglib.dynmicagent;

/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉
*
* @author 12061799
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class Test { /**
* 功能描述: <br>
* 〈功能详细描述〉
*
* @param args
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static void main(String[] args) {
BookFacadeProxy proxy = new BookFacadeProxy();
IBookFacade bookProxy = (IBookFacade) proxy.bind(new BookFacade());
bookProxy.addBook("红楼梦");
bookProxy.deleteBook();
}
}

3.    动态代理---CGLIB动态代理(MethodInterceptor 接口)

  CGLib (Code Generation Library) 是一个强大的,高性能,高质量的Code生成类库。它能够在执行期扩展Java类与实现Java接口。不仅仅能够接管接口类的方法,同时还能够接管普通类的方法.解决了jdk代理的只能代理接口类方法的难处,CGLib 的底层是Java字节码操作框架(ASM).动态的生成被代理类的子类, 增强的代码是硬编码在新生成的类文件内部的,不会存在反射的性能问题.下面是简单的代码实现:

3.1 建立被代理类

package jdkcglib.cglib;

/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉
*
* @author 12061799
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class BookFacade { public void addBook() {
System.out.println("增加图书的普通方法...");
} }

3.2 建立代理类

package jdkcglib.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; /**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉
*
* @author 12061799
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class BookFacadeCglib implements MethodInterceptor { private Object target; /**
* 创建代理对象
*
* @param target
* @return
*/
public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
} @Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("方法执行之前");
proxy.invokeSuper(obj, args);
System.out.println("方法执行之后");
return null;
} }

3.3  建立测试类

package jdkcglib.cglib;

import java.io.UnsupportedEncodingException;

/**
*
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉
*
* @author 12061799
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class TestCglib {
/**
*
* 功能描述: <br>
* 〈功能详细描述〉
*
* @param args
* @throws UnsupportedEncodingException
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static void main(String[] args) throws UnsupportedEncodingException {
BookFacadeCglib cglib = new BookFacadeCglib();
BookFacade bookCglib = (BookFacade) cglib.getInstance(new BookFacade());
bookCglib.addBook();
} }

三、  java代理小结

静态代理: 代理类就是通过调用被代理类的方法进行执行的,自己本身并不用清楚被代理类的方法.需要编译后执行.耦合比较紧密.

JDK动态代理: 利用反射原理,动态的生成代理类,将类的载入延迟到程序执行之中,解耦了代理类和被代理类的联系.主要要实现InvationHandler接口.

CGLIB动态代理:原理是继承,把被代理类作为父类,动态生成被代理类的子类,三个步骤,设置父类,设置回调函数,创建子类.实现MethodInterceptor 接口,拦截调用父类方法时,会处理回调方法,处理自己的增强方法.

参考:

http://www.cnblogs.com/bhlsheji/p/5316693.html

JAVA代理方式使用示例总结的更多相关文章

  1. java 代理的三种实现方式

    Java 代理模式有如下几种实现方式: 1.静态代理. 2.JDK动态代理. 3.CGLIB动态代理. 示例,有一个打招呼的接口.分别有两个实现,说hello,和握手.代码如下. 接口: public ...

  2. java两种动态代理方式的理解

    要理解动态代理,不妨先来看看一个静态代理的例子. 一.静态代理 以一个电商项目的例子来说明问题,比如我定义了一个订单的接口IOrder,其中有一个方法时delivery,代码如下. package c ...

  3. java中代理,静态代理,动态代理以及spring aop代理方式,实现原理统一汇总

    若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的. 通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类. ...

  4. Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)

    第一种代理即Java的动态代理方式上一篇已经分析,在这里不再介绍,现在我们先来了解下GCLIB代理是什么?它又是怎样实现的?和Java动态代理有什么区别? cglib(Code Generation ...

  5. Java代理模式示例程序

    Java代理模式示例程序 当然不是我想出来的,是我看的一个网上教程里的. 模拟的是一个对电脑公司的代理 真实类的接口: public interface SaleComputer { public S ...

  6. JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解

    在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...

  7. Java中3种代理总结(示例代码见之前文章)

    1.JDK静态代理 业务接口 接口的实现类 代理类,实现接口,并扩展实现类的功能 ### 2.JDK动态代理 业务接口 实现了业务接口的业务类 实现了InvocationHandler接口的handl ...

  8. Java代理模式

    java代理模式及动态代理类 1.      代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目 ...

  9. java代理的深入浅出(二)-CGLIB

    java代理的深入浅出(二)-CGLIB 1.基本原理 CGLIB的原理就是生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法.在子类中拦截所有父类方法的调用,拦截下来交给设置的Me ...

随机推荐

  1. struts 2 action result类型

    最近在管理公司老项目的时候发现如下代码: <bean name="detailPlayer" class="PlayAction" method=&quo ...

  2. UI Testing

    UI Test能帮助我们去验证一些UI元素的属性和状态.Apple 在 Xcode 7 中新加入了一套 UI Testing 的工具,其目的就是解决自动化UI测试这个问题.新的 UI Testing ...

  3. appium的等待

    在自动化过程中,元素出现受网络环境,设备性能等多种因素影响.因此元素加载的时间可能不一致,从而会导致元素无法定位超时报错,但是实际上元素是正常加载了的,只是出现时间晚一点而已.那么如何解决这个问题呢? ...

  4. HTTP 返回码中 301 与 302 的区别

    转自:http://blog.csdn.net/qmhball/article/details/7838989 一.官方说法301,302 都是HTTP状态的编码,都代表着某个URL发生了转移,不同之 ...

  5. python中字节与字符串的转换

    #bytes object    byte = b"byte example"     # str object    str = "str example" ...

  6. docker安装部署

    1. 如何安装 Epel源到 RHEL/CentOS 7/6/5? RHEL/CentOS rpm -ivh http://mirrors.ustc.edu.cn/epel/7/x86_64/Pack ...

  7. python笔记之json报错

    写爬虫的过程中不免遇到处理json数据的情况,今天在爬取新华网新闻数据时发现使用json.loads函数时报错: json.decoder.JSONDecodeError: Expecting val ...

  8. UOJ #214 合唱队形 (概率期望计数、DP、Min-Max容斥)

    9个月的心头大恨终于切掉了!!!! 非常好的一道题,不知为何uoj上被点了70个差评. 题目链接: http://uoj.ac/problem/214 题目大意: 请自行阅读. 题解: 官方题解讲得相 ...

  9. Nginx学习总结(2)——Nginx手机版和PC电脑版网站配置

    考虑到网站的在多种设备下的兼容性,有很多网站会有手机版和电脑版两个版本.访问同一个网站URL,当服务端识别出用户使用电脑访问,就打开电脑版的页面,用户如果使用手机访问,则会得到手机版的页面. 1.判断 ...

  10. LCS,LIS,LCIS

    网站:CSUST 8月3日(LCS,LIS,LCIS) LCS:      以下讲解来自:http://blog.csdn.net/yysdsyl/article/details/4226630 [问 ...