首先说一下动态代理和静态代理的差别:

静态代理:是预先写好或由特定工具自己主动生成的代码。再对其编译。在程序执行前。代理类的.class文件就已经存在了。

动态代理:代理是在程序执行时,运用反射机制动态创建而成的,程序执行之前,代理是不存在的。

Java的静态代理最简单的场景,一个接口,一个实现类,一个代理类就能够搞定。这个代理类持有接口实现类的引用,这样便能够实现托付对象的增强了。

Java的动态代理主要有两种。JDK动态代理和cglib动态代理

当中JDK动态代理,主要利用了接口InvocationHandler,还有Proxy类。

InvocationHandler接口: 

public interface InvocationHandler { 

 public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; 

}

參数说明: 

 Object proxy:指代理对象。 

 Method method:要调用的方法 

 Object[] args:方法调用时所须要的參数 

Proxy类: 

Proxy类是专门完毕代理的操作类,能够通过此类为一个或多个接口的实现类动态地生成代理类,此类提供了例如以下的操作方法: 

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

參数说明: 

 ClassLoader loader:类载入器 

 Class<?

>[] interfaces:得到所有的接口 

 InvocationHandler h:得到InvocationHandler接口的子类实例

动态代理类的字节码在程序执行时由Java反射机制动态生成。无需程序猿手工编写它的源码。动态代理类不仅简化了编程工作,并且提高了软件系统的可扩展性。由于Java 反射机制能够生成随意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。 以下看一下我写的一个小样例~

package go.derek;

interface Istudy
{
public void study(String words);
}

上面的接口定义了一个方法。

以下是这个接口的实现类

package go.derek;

class StudyImpl implements Istudy
{
public void study(String words){
System.out.println(words);
}
}

以下看一下代理类的代码

package go.derek;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
class StudyProxy implements InvocationHandler
{
private Object target;
public Object bind(Object target){
this.target=target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
} public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
System.out.println("start");
Object obj=method.invoke(target,args);
System.out.println("rest");
return obj;
} }

以下是測试类的代码

package go.derek;

class ProxyTest
{
public static void main(String[] args)
{
StudyProxy sp=new StudyProxy();
Istudy derek=(Istudy)sp.bind(new StudyImpl());
derek.study("I'm derek");
}
}

以下是输出结果:

start

I'm derek

rest

我们能够看出,代理类确实给托付类实现了增强,不能忽视的是代理类要持有托付类对象的引用。

JDK的动态代理机制仅仅能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理。cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖当中方法实现增强,但由于採用的是继承。所以不能对final修饰的类进行代理。

JDK动态代理具体解释的更多相关文章

  1. JDK动态代理

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

  2. 【原创】JDK动态代理,此次之后,永生难忘。

    动态代理,这个词在Java的世界里面经常被提起,尤其是对于部分(这里强调“部分”二字,因为有做了一两年就成大神的,实力强的令人发指,这类人无疑是非常懂动态代理这点小伎俩的)做了一两年新人来说,总是摸不 ...

  3. MyBatis Mapper 接口如何通过JDK动态代理来包装SqlSession 源码分析

    我们以往使用ibatis或者mybatis 都是以这种方式调用XML当中定义的CRUD标签来执行SQL 比如这样 <?xml version="1.0" encoding=& ...

  4. JDK 动态代理分析

    Java的代理有两种:静态代理和动态代理,动态代理又分为 基于jdk的动态代理 和 基于cglib的动态代理 ,两者都是通过动态生成代理类的方法实现的,但是基于jdk的动态代理需要委托类实现接口,基于 ...

  5. JDK动态代理[4]----ProxyGenerator生成代理类的字节码文件解析

    通过前面几篇的分析,我们知道代理类是通过Proxy类的ProxyClassFactory工厂生成的,这个工厂类会去调用ProxyGenerator类的generateProxyClass()方法来生成 ...

  6. Java JDK动态代理解析

    动态代理虽不常自己实现,但在Spring或MyBatis中都有重要应用.动态代理的意义在于生成一个占位(又称代理对象),来代理真实对象,从而控制真实对象的访问.Spring常JDK和CGLIB动态代理 ...

  7. JDK动态代理给Spring事务埋下的坑!

    一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...

  8. 转:jdk动态代理实现

    原文链接: jdk动态代理 注:文章中用常用的流程实现 动态代理,流程逻辑比较清晰.文章后面对 “为什么要使用接口” 原理分析还未细看. jdk的动态代理为什么用接口,内部是什么原理呢?看了几篇文章貌 ...

  9. (转)面试必备技能:JDK动态代理给Spring事务埋下的坑!

    一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...

随机推荐

  1. 【VBA编程】13.Workbook对象的事件

    Workbook事件用于响应对Workbook对象所进行的操作. [BeforeClose事件] BforeClose事件用于响应窗口关闭的操作 在工程资源器中,双击“ThisWorkbook”对象, ...

  2. C#创建COM组件供VB,PB,Delphi调用

    1  COM组件概述 COM是微软公司为了计算机工业的软件生产更加符合人类的行为方式开发的一种新的软件开发技术.在COM构架下,人们可以开发出各种各样的功能专一的组件,然后将它们按照需要组合起来,构成 ...

  3. ajax 异步 通信 小例子 servlet与 jsp异步 get

    get  请求参数通过 url那里写进去,然后send(null) html文件和 servlet进行通信 通过ajax 进行通信 <!DOCTYPE html PUBLIC "-// ...

  4. Bootstrap学习 进度条

    本文将介绍Bootstrap进度条,在本文中你将看到如何使用Bootstrap创建加载,重定向或动作状态的进度条 bootstrap进度条使用CSS3过渡和动画来获得该效果.Internet Expl ...

  5. jquery 设置checkbox选中 和获取选中值

    经常用到经常网上搜,这次写下来. 1,设置选中: $('#nrowid').prop('checked', false); 2,取选中项的值: $('#nrowid').prop("chec ...

  6. Asp.Net MVC之防止用户注入脚本参数

    假设有一个Controller,代码如下: public string Browse(string genre) { string message = "Store.Browse, Genr ...

  7. PHP时间戳和日期相互转换(文字有问题)

    在php中我们要把时间戳转换日期可以直接使用date函数来实现,如果要把日期转换成时间戳可以使用strtotime()函数实现,下面我来给大家举例说明. 1.php中时间转换函数 strtotime ...

  8. python对象序列化之pickle

    本片文章主要是对pickle官网的阅读记录. The pickle module implements binary protocols for serializing and de-serializ ...

  9. locationInView和translationInView的区别

      1  translationInView是UIPanGestureRecognizer下面的一个属性 locationInView则是UIGestureRecognizer下面的属性 2  tra ...

  10. css 的通用样式 设置 和倒计时功能 移动轮播图的手势滑动的功能

    body{ line-height:1.4; color:#333; font-family:arial; font-size: 12px; background:white; } input,tex ...