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. BZOJ 3943: [Usaco2015 Feb]SuperBull 最小生成树

    Code: // luogu-judger-enable-o2 #include<bits/stdc++.h> #define setIO(s) freopen(s".in&qu ...

  2. 【airtest, python】报错:requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(54, 'Connection reset by peer')),解决方法如下

    环境及设备 mac, xcode , iphonex 问题 最近出现一个让人费解的问题,airtest 没跑多长时间,服务就断掉,而且总是报“requests.exceptions.Connectio ...

  3. [luogu2679] 子串 (多维dp)

    传送门 Description 有两个仅包含小写英文字母的字符串 A 和 B . 现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来 ...

  4. Golang - 流程控制

    目录 Golang - 流程控制 1. 选择结构 2. 循环结构 3. 跳转语句 Golang - 流程控制 1. 选择结构 if else语句: //package 声明开头表示代码所属包 pack ...

  5. Bootstrap 表单控件一(单行输入框input,下拉选择框select ,文本域textarea)

    单行输入框,常见的文本输入框,也就是input的type属性值为text.在Bootstrap中使用input时也必须添加type类型,如果没有指定type类型,将无法得到正确的样式,因为Bootst ...

  6. QT的creator中图示

    不同的开发工具显示class和相关的用不同的图标表示.但大同小异.但对于QT的creator中图示确实不太好分.看图一目了然.

  7. 解决ExpressSpreadSheet 中文乱码问题[备查]

    cxSpreadSheet和F1Book等都提供了类似Excel的操作, 但是相比F1Book, cxSpreadSheet的中文支持还不是很完善.在设置了wordbreak为true的时候,里面的中 ...

  8. 【习题 4-9 UVA - 815】Flooded!

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 题目很迷啊. 不会出现盆地? 可以理解为一条线. 从左往右高度上升的一座座山. 然后V升的水从最左边的山倒进去. 然后问你最后海拔多 ...

  9. 【codeforces 798A】Mike and palindrome

    [题目链接]:http://codeforces.com/contest/798/problem/A [题意] 让你严格改变一个字符,使得改变后的字符串为一个回文串; 让你输出可不可能; [题解] 直 ...

  10. 一文快速上手Logstash

    原文地址:https://cloud.tencent.com/developer/article/1353068 Elasticsearch是当前主流的分布式大数据存储和搜索引擎,可以为用户提供强大的 ...