代理模式:为某些对象提供代理以实现对这个对象的访问。

对一个对象进行访问控制的原因是为了只有在我们确实需要这个对象时才对它进行创建和初始化。

一般包括以下组件:

被代理者接口:提供被代理者的访问途径。

被代理者:定义真实对象。

代理者:保存一个被代理者的引用, 并对外提供统一的代理方法, 可以对被代理者的方法实现修饰和控制。

要生成某一个对象的代理对象,这个代理对象通常也要编写一个类来生成,所以首先要编写用于生成代理对象的类。java在JDK1.5之后提供了java.lang.reflect.Proxy类,通过Proxy类提供的newProxyInstance方法用来创建一个对象的代理对象,这个方法总共有3个参数,ClassLoader loader用来指明生成代理对象使用哪个类装载器,Class<?>[] interfaces用来指明生成哪个对象的代理对象,通过接口指定,InvocationHandler 用来指明产生的这个代理对象要做什么事情。所以只需要调用newProxyInstance方法就可以得到某一个对象的代理对象了。

代理类需要实现InvocationHandler接口,该接口只有一个invoke方法,用于自定义代理行为.

JDK动态代理示例

----------------

//代理接口
public interface IClient {
void doSomething(String thing);
}

-

//被代理者
public class Client implements IClient {
@Override
public void doSomething(String thing) {
System.out.println("do a thing:" + thing);
}
}

-

//代理
public class ProxyAgent implements InvocationHandler {
private Object client; public ProxyAgent(Object client) {
this.client = client;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 这里可以对method进行过滤或添加其他代码,然后调具体对象的方法
Object object = method.invoke(client, args);
return object;
} //获取代理实例
public Object getProxy(){
return Proxy.newProxyInstance(getClass().getClassLoader(), client.getClass().getInterfaces(), this);
} public static void main(String[] args){
//被代理者
Client client = new Client();
//代理者
IClient proxy = (IClient) new ProxyAgent(client).getProxy();
//调用代理动作
proxy.doSomething("buy something");
}
}

----------------

由上可见,使用JDK的Proxy实现动态代理有一个要求:被代理的类必须实现接口,未实现接口则没办法完成动态代理。

实际中有些类没有实现接口,不应该为了实现动态代理而去抽出一些没有实例意义的接口,可以通过cglib对一个类实现代理。

<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.4</version>
</dependency>

示例如下:

package cn.luan.demo;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; /*
* 动态代理类
*/
public class DynamicProxy implements MethodInterceptor { // 被代理对象
Object targetObject; // 动态生成一个新的类,使用父类的无参构造方法创建一个指定了特定回调的代理实例
public Object getProxyObject(Object object) {
//set被代理对象
this.targetObject = object;
//动态代码生成器
Enhancer enhancer=new Enhancer();
//回调方法
enhancer.setCallback(this);
//设置生成类的父类类型
enhancer.setSuperclass(targetObject.getClass());
//动态生成字节码并返回代理对象
return enhancer.create();
} // 实现了一个方法拦截器接口
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("方法调用前织入的横切内容");
System.out.println("method name: " + method.getName()); // 调用方法
Object result = methodProxy.invoke(targetObject, args); System.out.println("方法调用后织入的横切内容"); return result;
} //测试
public static void main(String[] args) {
Client client = (Client) new DynamicProxy().getProxyObject(new Client());
client.doSomething("cglib proxy");
}
}

--cglib不能对final类做代理

end

Java动态代理 cglib的更多相关文章

  1. Java动态代理--CGLib实现

    上一篇说了通过JDK实现实现了动态代理,但是用JDK实现代理,要求所代理的类必须实现一个接口.如果我们类不实现接口,这就在无法使用JDK提供的Proxy来实现动态代理,这个时候我们应该怎么办呢?我们找 ...

  2. [转]java动态代理(JDK和cglib)

    转自:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html java动态代理(JDK和cglib) JAVA的动态代理 代理模式 代理 ...

  3. Java静态代理&动态代理&Cglib代理详解

    一.静态代理 根据被代理的类的时机的不同,如果在编译阶段就能确定下来的被代理的类是哪一个,那么,就可以使用静态代理的方式. 申明一个接口: /** * @author jiaqing.xu@hand- ...

  4. CGLIB和Java动态代理的区别(笔记)

    java常用知识点: 1.Java动态代理只能够对接口进行代理,不能对普通的类进行代理(因为所有生成的代理类的父类为Proxy,Java类继承机制不允许多重继承):CGLIB能够代理普通类:2.Jav ...

  5. Java动态代理与CGLib

    Java帝国之动态代理 CGLib:从兄弟到父子-动态代理在民间是怎么玩的? 以上两篇文章引用自微信公众号: 码农翻身 Java动态代理 深度详解 以上文章引用博客园:陈树义

  6. Java动态代理(三)——Cglib动态代理

    一.Cglib动态代理Cglib是一个优秀的动态代理框架,它的底层使用ASM在内存中动态的生成被代理类的子类,使用Cglib即使代理类没有实现任何接口也可以实现动态代理功能.而且,它的运行速度要远远快 ...

  7. java动态代理(JDK和CGLIB)笔记

    动态代理:为一堆interface或类的实现提供统一的执行通道,从含义上就像局域网电脑通过代理上网一样,走统一的通道,代理控制通道,自然可以在通道里加上自定义实现,例如像AOP切面,日志等. JDK的 ...

  8. Java动态代理全面分析

    代理模式 解说:给某一个对象提供一个代理,并由代理对象控制对原对象的引用: 代理模式需要以下几个角色: 1  主题:规定代理类和真实对象共同对外暴露的接口: 2  代理类:专门代理真实对象的类: 3 ...

  9. Java 动态代理作用是什么?

    Java 动态代理作用是什么?   1 条评论 分享   默认排序按时间排序 19 个回答 133赞同反对,不会显示你的姓名 Intopass 程序员,近期沉迷于动漫ING 133 人赞同 ① 首先你 ...

随机推荐

  1. ASP.NET状态管理策略

    如果要想把信息存储在客户端那可以选择视图状态.控件状态.隐藏字段.cookie.和查询字符串. 1.web窗体页提供viewstate属性作为内置结构,在同一页的多个请求间自动保留值.他作为页面的隐藏 ...

  2. java文件下载 rest

    /** * 返回文件二进制 * */ @GET @Path("/excel") @Produces("application/vnd.ms-excel; charset= ...

  3. 夺命雷公狗---node.js---4net模块(上)

    node.js为我们提供了一个net模块,主要是为了提供了一些底层通信的小工具,包含了创建服务器/客户端方法,引入方式也很简单: var net = require('net'); net模块也为我们 ...

  4. 夺命雷公狗jquery---3普通选择器

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  5. [python] No module named _sysconfigdata_nd

    when setting python environment in Ubuntu13.04, i got this error: ImportError: No module named _sysc ...

  6. ASP.NET MVC API 路由生成规则

    我们都知道调用ASP.NET MVC的某些API函数(诸如:Url.Action.RedirectToAction等)可以生成URL,ASP.NET MVC会根据调用API函数时传入的参数去匹配系统定 ...

  7. Three.js - 网页3D应用的普及已经指日可待了

    Three.js可以高效实现3D效果,真不赖.

  8. 操作系统双语阅读 - Schedulers调度器2

    Most processes can be described as either I/O bound or CPU bound. 大多数进程都可以描述为IO绑定或者CPU绑定. An I/O-bou ...

  9. !important------至高无上的宝剑

    如上图,不同来源的两个样式,第一个样式设置了font-weight,第二个没有,浏览器会把它叠加在一起,即浏览器会把各个零散的整合成一个整体.第一个样式color:red,第二个样式color:blu ...

  10. Hadoop3.0新特性介绍,比Spark快10倍的Hadoop3.0新特性

    Hadoop3.0新特性介绍,比Spark快10倍的Hadoop3.0新特性 Apache hadoop 项目组最新消息,hadoop3.x以后将会调整方案架构,将Mapreduce 基于内存+io+ ...