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. php第四节课

    对象 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.o ...

  2. Linux思维导图之查找命令

    常用查找命令的区别:

  3. greenplum数据迁移

    源集群: 登录集群su - gpadminpsql -d postgres查询数据库信息\l查询用户信息\du 备份需要迁移的库到指定目录pg_dump -C testdata > /home/ ...

  4. Python列表、集合与字典(3)

    目录 一.列表 二.集合 三.字典 一.列表 1. 列表初识   列表的使用为处理特定顺序排列的数据提供了便利,列表元素可以是字母.数字或者其他信息,同时所加元素之间不存在任何关系.   在Pytho ...

  5. 11. IDEA 在同一工作空间创建多个项目

    1.创建项目 二..创建工作空间 JavaWorkspace 1.File-> New Project -> 创建工作空间 JavaWorkspace,并 顺便创建项目 JavaOne 2 ...

  6. Spring Boot错误:Unable to start embedded container...的问题解决

    解决方法: 1.用错了注解,改用以下注解: @SpringBootApplication 相当于:@Configuration.@ServletComponentScan.@EnableAutoCon ...

  7. Android Studio 导入的项目编码错误问题

    错误提示: Error:(4, 35) 閿欒: 缂栫爜UTF-8鐨勪笉鍙槧灏勫瓧绗? 解决方法: 1). 2). 的下面添加下面的一行语句: android{compileOptions.enco ...

  8. chcp - 设置或者显示活动代码页编号

    chcp - 设置或者显示活动代码页编号 学习了:https://baike.baidu.com/item/CHCP/9061635?fr=aladdin

  9. Linux命令(八)——vi编辑器的使用

    vi编辑器是linux系统下的标准正文编辑器,有三种基本模式:命令行模式.插入模式和底行命令模式. 1.命令行模式:控制屏幕光标的移动,字符.字或行的删除,移动复制某区段及进入插入模式或底行命令模式下 ...

  10. HTTP缓存和CDN缓存

    一 http缓存 1.1缓存的分类: http中具有缓存功能的是:1.浏览器缓存.  2.缓存代理服务器. 1.2 什么是缓存: http缓存的是指:当Web请求抵达缓存时, 如果本地有“已缓存的”副 ...