JAVA动态代理详解

1.什么是代理

代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。

2.什么是动态代理

在程序运行时,运用反射机制动态创建代理实例对象。JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理。

相关类与接口

java.lang.reflect.Proxy:这是 Java 动态代理机制的主类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。 

// 方法:该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例
static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

java.lang.reflect.InvocationHandler:这是调用处理器接口,它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。 

//方法:调用处理器根据这三个参数进行预处理或分派到委托类实例上发射执行
Object invoke(Object proxy, Method method, Object[] args)

3.动态代理示例

代理类
public class LogHandler implements InvocationHandler {

    private Object targetObject;

    public Object newProxyInstance(Object targetObject) {
        this.targetObject = targetObject;
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
                               targetObject.getClass().getInterfaces(), this);
    }

    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("start-->>" + method.getName());
        for (int i=0; i<args.length; i++) {
            System.out.println(args[i]);
        }
        Object ret = null;
        try {
            //调用目标方法
            ret = method.invoke(targetObject, args);
            System.out.println("success-->>" + method.getName());
        }catch(Exception e) {
            e.printStackTrace();
            System.out.println("error-->>" + method.getName());
            throw e;
        }
        return ret;
    }

}
接口类
public interface UserManager {

    public void addUser(String userId, String userName);
}
目标类
package com.bjpowernode.pattern;

public class UserManagerImpl implements UserManager {

    public void addUser(String userId, String userName) {
        //System.out.println("start-->>addUser() userId-->>" + userId);
        try {
            System.out.println("AddUser" );
}
    }
}
客户端
public class Client {

    /**
     * @param args
     */
    public static void main(String[] args) {
        LogHandler logHandler = new LogHandler();
        UserManager userManager = (UserManager)logHandler.newProxyInstance(new UserManagerImpl());
        userManager.addUser("0001","张三");    }

}

4.动态代理类与静态代理的区别:

由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。动态代理类:在程序运行时,运用反射机制动态创建而成。无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。

5.动态类的应用场景

不允许直接访问某些类;对访问要做特殊处理等。或者,要对原方法进行统一的扩展,例如加入日志记录。

6.什么是CGLIB动态代理

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

7.CGLIB示例

委托类:

package com.orient.cglib;

public class BookFacadeImpl1 {
    public void addBook() {
        System.out.println("增加图书的普通方法...");
    }
}

代理类

package com.orient.cglib;

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 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;  

    }  

}

测试类

package com.orient.cglib;

public class TestCglib {
    public static void main(String[] args) {
        BookFacadeCglib cglib=new BookFacadeCglib();
        BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1());
        bookCglib.addBook();
    }
}

这个工程依赖于cglib.jar 和asm.jar

时间: 2024-12-23 08:25:41

JAVA动态代理详解的相关文章

java动态代理详解,并用动态代理和注解实现日志记录功能

动态代理的概念 动态代理是程序在运行过程中自动创建一个代理对象来代替被代理的对象去执行相应的操作,例如, 我们有一个已经投入运行的项目中有一个用户DAO类UserDao用来对User对象进行数据库的增删改查操作,但是有一天,要求在对用户的增删改查操作时记录相应的日志,这是怎么办呢?难道我们去直接修改UserDao的源代码,然后在UserDao的每个方法中加入日志记录功能,这显然是不合理的,它违背了java的OCP原则,即对修改关闭对扩张开放.比如改现有的代码如下: 接口类 public inte

Java 动态代理详解

package com.at221; //代理设计模式: interface ClothFactory{ void product(); } class NikeFactory implements ClothFactory{//被代理类: @Override public void product() { System.out.println("Nike服装很可靠"); } } class ProxyFactory implements ClothFactory{//代理类: pri

Cglib动态代理详解

查阅了很多资料,这样理解起来好像可以一起呵成,不知道有没有什么地方不对,有的话希望大家指导一下 Cglib动态代理 JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理. 示例 : Jar 包 : cglib-2.2.jar, asm-all-3.1 Helloworld 方法 package com.grey

动态代理详解

1 学习动态代理的目的 动态代理技术都是在框架中使用,例如:Struts1.Struts2.Spring和Hibernate中都使用了动态代理技术.如果你不想自己写个框架,那么你基本上是用上不动态代理技术的.学习动态代理技术的目的是为了更好的理解框架内部的原理,也就是说是为了将来学习框架打基础!动态代理技术有点难度!而且明白了动态代理技术可能一时也想不到他适合在什么情况下使用它.这些东西都会在学习框架时渐渐明白. 2 运行时实现指定的接口 想实现某个接口,你需要写一个类,然后在类名字的后面给出"

JDK动态代理详解

首先说一下动态代理和静态代理的区别: 静态代理:是预先写好或由特定工具自动生成的代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了. 动态代理:代理是在程序运行时,运用反射机制动态创建而成的,程序运行之前,代理是不存在的. Java的静态代理最简单的场景,一个接口,一个实现类,一个代理类就可以搞定,这个代理类持有接口实现类的引用,这样便可以实现委托对象的增强了. Java的动态代理主要有两种,JDK动态代理和cglib动态代理 其中JDK动态代理,主要利用了接口Invocati

JDK动态代理、CGLIB动态代理详解

一.JDK动态代理 1.1 接口类 package jdkproxy; /** * @author admin *接口类 */ public interface IBookManage { //添加图书 public void addBook(); } 1.2 接口实现类 package jdkproxy; /** * @author admin *接口实现类 */ public class BookManage implements IBookManage { @Override public

详解java动态代理

生活中的代理: 比如一个明星成名了以后,是需要有一个代理的,因为太多人想找他签名,应付不来,那么这个时候代理的作用是拦截你对真正明星的访问,他可以拦截下来收点费用,再叫真正的明星过来为你签名. 程序中的代理: 1,要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理.日志.计算方法的运行时间.事务管理.等等,你准备如何做? 2,编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码 下图显示了在程序中代理的调用原理(

好程序员Java教程Java动态代理机制详解

好程序员Java教程Java动态代理机制详解:在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的.首先我们先来看看java的API帮助文档是怎么样对这两个类进行描述的: InvocationHandler: 1InvocationHandler is the interface implemented by the invocation handle

java 动态代理的学习详解

再讲java动态代理前,先来看看代理模式. Proxy类通过组合,对Hello类进行了增强,并对其进行了委托. 代理模式代码: public class ProxyPattern { interface IHello{ void say() ; } static class Hello implements IHello{ public void say(){ System.out.println("hello world"); } } static class Proxy imple