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 1108: [POI2007]天然气管道Gaz 性质分析_小结论_巧妙

    Description Mary试图控制成都的天然气市场.专家已经标示出了最好的天然气井和中转站在成都的地图.现在需要将中转 站和天然气井连接起来.每个中转站必须被连接到正好一个钻油井,反之亦然. M ...

  2. RabbitMQ出现服务启动几秒退出问题

    最近在学习rebbitmq, 1.首先安装了otp_win64_20.3, 2.erlang安装完成需要配置erlang环境变量: 这个是新建的 文档是:ERLANG_HOME D:\develop\ ...

  3. 文献阅读 | Benefits and limitations of genome-wide association studies

    参考:今日阅读:GWAS的优劣势 - Omics Liu  Omics 待续~

  4. 日记——OI历程

    学OI也一年多了(2015.12-),一直没学出个像样的东西.相比dalao们,我还是弱爆了. ljj,qyf,yyf三位三区dalao. xxy,myj两位三区学长dalao. 稍微总结一下前一段时 ...

  5. [51Nod 1218] 最长递增子序列 V2 (LIS)

    传送门 Description 数组A包含N个整数.设S为A的子序列且S中的元素是递增的,则S为A的递增子序列.如果S的长度是所有递增子序列中最长的,则称S为A的最长递增子序列(LIS).A的LIS可 ...

  6. 30.es增删改内部分发原理

    当客户端发送一次请求时,大致会经过以下几个步骤     (1)客户端发送一个请求过去,es的一个node接收到这个请求(随机的),这个node就被es内部分配成coordinating node(协调 ...

  7. ThinkPHP5.0 模型查询操作

    1.获取单个数据 //取出主键为1的数据 $user = User::get(1); echo $user->name; // 使用数组查询 $user = User::get(['name' ...

  8. 学习EXTJS6(6)基本功能-工具栏和菜单

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  9. 传输模型,网络层次划分,三次握手,四次挥手,IP与端口,套接字socket

    了解套接字之前,需要先了解基本的传输模型 其次,还需要了解网络的七层划分和四层结构 在python中,数据链路层相当于硬件层,python不需要了解,只用在传输层进行学习就足够了 其中,传输层分为TC ...

  10. elasticsearch 权威指南搜索阅读笔记(四)

    多索引多type搜索 分页搜索 每页5条 查询一到3页数据 第一页:http://127.0.0.1:9200/blogs2/product/_search?size=5&from=0 第二页 ...