1.何为代理
  代理,即代替主角完成一些额外的事情。例如,明星都有经纪人,明星参演电影之前,经纪人作为明星的代理人和出资方洽谈片酬、排期等,而真正参与拍戏的还是明星本人,明星拍完戏后,由经纪人代理明星去清算片酬等。Java中的代理机制就是在目标方法执行前后执行一些额外的操作,如安全检查、记录日志等,Java中的代理分为静态代理和动态代理。

2.静态代理
  首先看一下静态代理,直接上代码,代码模拟了登录操作。

public interface LoginService {
void login();
}
public class LoginServiceImpl implements LoginService {
@Override
public void login() {
System.out.println("login");
}
}
public class LoginServiceProxy implements LoginService {
private LoginService loginService;
public LoginServiceProxy(LoginService loginService) {
this.loginService = loginService;
}
@Override
public void login() {
beforeLogin();
loginService.login();
afterLogin();
}
private void beforeLogin() {
System.out.println("before login");
}
private void afterLogin() {
System.out.println("after login");
}
}
public class Client {
@Test
public void test() {
LoginService loginService = new LoginServiceImpl();
LoginService loginServiceProxy = new LoginServiceProxy(loginService);
loginServiceProxy.login();
}
}

输出结果如下:

before login
login
after login

上面代码实现的静态代理很容易理解,使用聚合方式,在登录操作前后执行额外的操作。静态代理方式可以看得到具体代理类的代码,且代码由程序员编写,在编译之后会生成相应的class文件。使用静态代理方式的缺点,如果需要对LoginService接口中有N个方法都代理,则需要在代理类中创建N个代理方法,并且需要编写重复的代理操作代码。

3.概念解释
  目标接口,即对目标操作的抽象,如LoginService。
  目标类,即目标接口的实现类,如LoginServiceImpl。
  目标对象,即目标类的实例。
  代理类,即目标类的代理,如LoginServiceProxy。
  代理对象,即代理类的实例。

4.动态代理
  动态代理,即在运行时根据目标接口动态生成的代理类。动态代理方式生成的代理类在编译后不会生成实际的class文件,而是在运行时动态生成类字节码,并加载到JVM中使用。下面使用JDK的动态代理机制模拟登录操作,具体代码如下。

public interface LoginService {
void login();
}
public class LoginServiceImpl implements LoginService {
@Override
public void login() {
System.out.println("login");
}
}
public class ProxyInvocationHandler implements InvocationHandler {
private LoginService loginService;
public ProxyInvocationHandler(LoginService loginService) {
this.loginService = loginService;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
beforeLogin();
Object invokeResult = method.invoke(loginService, args);
afterLogin();
return invokeResult;
}
private void beforeLogin() {
System.out.println("before login");
}
private void afterLogin() {
System.out.println("after login");
}
}
public class Client {
@Test
public void test() {
LoginService loginService = new LoginServiceImpl();
ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler(loginService);
LoginService loginServiceProxy = (LoginService) Proxy.newProxyInstance(loginService.getClass().getClassLoader(), loginService.getClass().getInterfaces(), proxyInvocationHandler);
loginServiceProxy.login();
createProxyClassFile();
}
public static void createProxyClassFile() {
String name = "LoginServiceProxy";
byte[] data = ProxyGenerator.generateProxyClass(name, new Class[]{LoginService.class});
try {
FileOutputStream out = new FileOutputStream("/Users/" + name + ".class");
out.write(data);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

  输出结果如下。

before login
login
after login

  JDK动态代理方式实现代理的步骤如下:
  1.编写目标接口;
  2.编写目标类实现目标接口,实现目标方法的具体逻辑;
  3.编写一个代理处理器类实现InvocationHandler接口,重写invoke方法,用于指定运行时将生成的代理类需要完成的具体操作,包括beforeLogin和afterLogin。代理对象调用任何代理方法时都会调用这个invoke方法;
  4.创建代理对象,使用代理对象调用代理方法。

  上面的步骤中主要涉及以下两个类:java.lang.reflect.InvocationHandler和java.lang.reflect.Proxy。InvocationHandler是一个接口,代理类的调用处理器,每个代理对象都具有一个关联的调用处理器,用于指定动态生成的代理类需要完成的具体操作。该接口中有一个invoke方法,代理对象调用任何目标接口的方法时都会调用这个invoke方法,在这个方法中进行目标类的目标方法的调用。Proxy提供静态方法用于创建动态代理类和代理类实例,同时,使用它提供的方法创建的代理类都是它的子类。这个类中主要关注newProxyInstance方法,该方法用于创建代理类对象,方法声明如下:

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

loader参数用于指示使用哪个类加载器加载这个代理类;interfaces表示代理类实现的接口列表;h表示使用哪个调用处理器。

  后续文章《深入浅出JDK动态代理(二)》会深入源码分析JDK动态代理生成的代理类是什么样,为什么调用代理类的任何方法时都一定会调用invoke方法,值得期待!

  

深入浅出JDK动态代理(一)的更多相关文章

  1. JDK动态代理实例

    最近看<深入浅出MyBatis技术原理与实战>这本书时,里面讲到Mapper接口的内部实现是通过JDK动态代理生成实现类,联想到之前看<SPRING技术内幕>这本书里也常常提到 ...

  2. JDK动态代理

    一.基本概念 1.什么是代理? 在阐述JDK动态代理之前,我们很有必要先来弄明白代理的概念.代理这个词本身并不是计算机专用术语,它是生活中一个常用的概念.这里引用维基百科上的一句话对代理进行定义: A ...

  3. 静态代理和利用反射形成的动态代理(JDK动态代理)

    代理模式 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 静态代理 1.新建 ...

  4. Spring中的JDK动态代理

    Spring中的JDK动态代理 在JDK1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在动态代理是实现AOP的绝好底层 ...

  5. AOP学习心得&jdk动态代理与cglib比较

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...

  6. JDK动态代理的实现原理

    学习JDK动态代理,从源码层次来理解其实现原理参考:http://blog.csdn.net/jiankunking/article/details/52143504

  7. Java中的JDK动态代理

    所谓代理,其实就是相当于一个中间人,当客户端需要服务端的服务时,不是客户直接去找服务,而是客户先去找代理,告诉代理需要什么服务,然后代理再去服务端找服务,最后将结果返回给客户. 在日常生活中,就拿买火 ...

  8. JDK动态代理与CGLib动态代理

    1.JDK动态代理 JDK1.3以后java提供了动态代理技术,允许开发者在运行期创建接口的代理实例,动态代理是实现AOP的绝好底层技术. JDK的动态代理主要涉及到java.lang.reflect ...

  9. jdk动态代理实现

    1.jdk动态代理的简单实现类 package com.proxy; import java.lang.reflect.InvocationHandler; import java.lang.refl ...

随机推荐

  1. bootstrap与jQuery结合的动态进度条

    此款进度条实现的功能: 1.利用了bootstrap的进度条组件. a.在最外层的<div>中加入class .progress,在里层<div>加入class .progre ...

  2. 优动漫PAINT发展历程和主要功能

    优动漫PAINT也就是我们常说的clip studio paint(CSP)的中文版本,它是一款功能强大的动漫绘图软件.经过五年的成长,优动漫PAINT经历了从青涩到成熟的发展过程,随着软件更多功能的 ...

  3. python 跑服务器,访问自己制作的简单页面

    1  python 跑服务器,访问自己制作的简单页面 2 # win+b出现一个网址http:/0.0.1:5000/复制到浏览器查看# http://127.0.0.1:5000/home 做这个首 ...

  4. JS 从100里面随机取10个数比大小

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

  5. Linux进程地址管理之mm_struct

    FROM : http://www.cnblogs.com/Rofael/archive/2013/04/13/3019153.html Linux对于内存的管理涉及到非常多的方面,这篇文章首先从对进 ...

  6. 【hihocoder 1303】模线性方程组

    [题目链接]:http://hihocoder.com/problemset/problem/1303 [题意] [题解] /* x % m[1] = r[1] x % m[2] = r[2] x = ...

  7. 洛谷——P1115 最大子段和

    https://www.luogu.org/problem/show?pid=1115#sub 题目描述 给出一段序列,选出其中连续且非空的一段使得这段和最大. 输入输出格式 输入格式: 输入文件ma ...

  8. 一起写RPC

    http://blog.csdn.net/linuu?viewmode=contents

  9. [Linux]第五部分-Linux系统管理员

    启动流程如下:1.加载BIOS信息,读取第一个启动设备代号2.读取第一个启动设备的Mbr引导程序的启动信息3.加载操作系统核心信息4.核心执行init程序并获取运行信息5.init执行 /etc/rc ...

  10. Linux下I/O复用 Select与Poll

    Select #include <sys/time.h>#include <sys/types.h>#include <sys/unistd.h> int sele ...