Java 静态代理和动态代理

1、静态代理,实现代码如下,实际上是对装饰器模式的一种应用

interface UserManager {
    public void addUser();
}

class UserManagerImpl implements UserManager {
    public void addUser() {
        System.out.println("raw addUser");
    }
}

class UserManagerImplProxy implements UserManager {
    private UserManager userManager;
    
    public UserManagerImplProxy(UserManager userManager) {
        this.userManager = userManager;
    }
    
    public void addUser() {
        System.out.println("in proxy");
        userManager.addUser();
    }
}
public class ProxyTest {
    public static void main(String args[]) {
        UserManager userManager = new UserManagerImplProxy(new UserManagerImpl());
        userManager.addUser();
    }
}

2、动态AOP,借助 java.lang.reflect.InvocationHandler接口 和 java.lang.reflect.Proxy 类实现 

java.lang.reflect.InvocationHandler接口的定义如下:

public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}

Object proxy:被代理的对象

Method method:要调用的方法

Object[] args:方法调用时所需要参数

invoke 方法用于切面处理,调用相应的方法

java.lang.reflect.Proxy类的定义如下:

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

CLassLoader loader: 类的加载器

Class<?> interfaces: 得到全部的接口

InvocationHandler h: 实现 InvocationHandler 接口的子类的实例

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface UserManager {
    public void addUser();
}

class UserManagerImpl implements UserManager {
    public void addUser() {
        System.out.println("raw addUser");
    }
}

class UserManagerImplProxy implements InvocationHandler {
    
    private Object targetObject;
    
    public void log() {
        System.out.println("message info");
    }
    
    public Object createProxyInstance(Object targetObject) {
        this.targetObject = targetObject;
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        log();
        Object ret = method.invoke(targetObject, args);
        return ret;
    }
}
public class ProxyTest {
    public static void main(String args[]) {
        UserManagerImplProxy proxy = new UserManagerImplProxy();
        UserManager manager = (UserManager) proxy.createProxyInstance(new UserManagerImpl());
        manager.addUser();
    }
}

3、动态代码字节生成

CGLib是动态代码字节生成的实现,它封装字节码生成工具Asm,原理是在运行期间目标字节码加载后,生成目标类的子类,将切面逻辑加入到子类中,所以使用Cglib实现AOP不需要基于接口。cglib 的核心是实现 MethodInterceptor 接口,使用 intercept() 方法进行面向切面的处理,调用相应的通知。其中 cglib 中有一个 Enhancer 类,可以使用他快速的创建一个代理类。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

interface UserManager {
    public void addUser();
}

class UserManagerImpl implements UserManager {
    public void addUser() {
        System.out.println("raw addUser");
    }
}

class CGLIBProxyFactory implements MethodInterceptor{
    // 要放回的代理对象
    private Object obj;

    public Object createProxy(Object obj) {
        // 把传进来的代理对象赋值给obj
        this.obj = obj;
        Enhancer enhancer = new Enhancer();
        // 需要为其实例指定一个父类,也就是我们 的目标对象,那么我们新创建出来的对象就是目标对象的子类,有目标对象的一样
        enhancer.setSuperclass(this.obj.getClass());
        // 除此之外,还要指定一个回调函数,这个函数就和Proxy的 invoke()类似
        enhancer.setCallback(this);
        return enhancer.create();

    }
    
    public void log() {
        System.out.println("message info");
    }
    
    @Override
    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object proxyObject = null;
        UserManagerImpl um = (UserManagerImpl) obj;
        log();
        proxyObject = methodProxy.invoke(um, args);
        return proxyObject;
    }

}

public class ProxyTest {
    public static void main(String args[]) {
        CGLIBProxyFactory gb = new CGLIBProxyFactory();
        UserManager manager = (UserManager)gb.createProxy(new UserManagerImpl());
        manager.addUser();
    }
}
原文地址:https://www.cnblogs.com/m2492565210/p/7250628.html