JAVA代理方式使用示例总结
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代理方式使用示例总结的更多相关文章
- java 代理的三种实现方式
Java 代理模式有如下几种实现方式: 1.静态代理. 2.JDK动态代理. 3.CGLIB动态代理. 示例,有一个打招呼的接口.分别有两个实现,说hello,和握手.代码如下. 接口: public ...
- java两种动态代理方式的理解
要理解动态代理,不妨先来看看一个静态代理的例子. 一.静态代理 以一个电商项目的例子来说明问题,比如我定义了一个订单的接口IOrder,其中有一个方法时delivery,代码如下. package c ...
- java中代理,静态代理,动态代理以及spring aop代理方式,实现原理统一汇总
若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的. 通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类. ...
- Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)
第一种代理即Java的动态代理方式上一篇已经分析,在这里不再介绍,现在我们先来了解下GCLIB代理是什么?它又是怎样实现的?和Java动态代理有什么区别? cglib(Code Generation ...
- Java代理模式示例程序
Java代理模式示例程序 当然不是我想出来的,是我看的一个网上教程里的. 模拟的是一个对电脑公司的代理 真实类的接口: public interface SaleComputer { public S ...
- JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解
在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...
- Java中3种代理总结(示例代码见之前文章)
1.JDK静态代理 业务接口 接口的实现类 代理类,实现接口,并扩展实现类的功能 ### 2.JDK动态代理 业务接口 实现了业务接口的业务类 实现了InvocationHandler接口的handl ...
- Java代理模式
java代理模式及动态代理类 1. 代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目 ...
- java代理的深入浅出(二)-CGLIB
java代理的深入浅出(二)-CGLIB 1.基本原理 CGLIB的原理就是生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法.在子类中拦截所有父类方法的调用,拦截下来交给设置的Me ...
随机推荐
- BZOJ 1827: [Usaco2010 Mar]gather 奶牛大集会 树形DP + 带权重心
Description Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来举办这次集会.每个奶牛居住在 N(1<=N<=100,0 ...
- Nginx设置alias别名目录访问phpmyadmin
引言:Nginx服务器通过设置alias别名可以使特定的目录(phpmyadmin目录)不出现在网站根目录下面,即使网站根目录被攻破,也不会影响到phpmyadmin目录里面的文件. 说明: 站点:h ...
- 我理解的数据结构(三)—— 队列(Queue)
我理解的数据结构(三)-- 队列(Queue) 一.队列 队列是一种线性结构 相比数组,队列对应的操作是数组的子集 只能从一端(队尾)添加元素,只能从另一端(队首)取出元素 队列是一种先进先出的数据结 ...
- Selenium调用JavaScript修改元素属性
修改元素的style,主要是将一些隐性元素显示出来,让元素可被操作: JavascriptExecutor js = (JavascriptExecutor)driver; js.executeSc ...
- java并发之停止线程
停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作.停止一个线程可以用Thread.stop()方法,但最好不要用它.虽然它确实可以停止一个正在运行的线程,但是这个方法是不安 ...
- Ngnix--知识点
ngnix擅长负载 均衡的反向代理 haproxy擅长高可用的反向代理,这个还支持TCP协议 ngnix只能支持HTTP和Email(这个HTTPS需要核实一下) ngnix和haproxy都需要ke ...
- sass基础教程
1. 使用变量; $highlight-color: #F90; .selected { border: 1px solid $highlight-color; } //编译后 .selected { ...
- JAVAEE之-----MySQL分页技术(带搜索)
需求: 为什么须要採用分页技术呢?在数据库中我们查询数据的时候,须要将数据返回到显示页面.数据库中含有大量数据,所有显示在一个页面过于太多,所以我们须要採用分页技术.每一页显示不同数据. 主要解决这个 ...
- 仿支付宝/微信的password输入框效果GridPasswordView解析
仿支付宝/微信的password输入框效果GridPasswordView解析,把一些设置和一些关键的地方列了出来,方便大家使用,可能能够省一部分的时间,也算是自己的积累吧. 1.password框能 ...
- 【待解决】An internal error occurred during: "Launching baiduTest1". java.lang.NullPointerException
编写的一个Java类,以junit运行可以正常执行,以testNG执行就报如下错误 解决方法: