zoukankan      html  css  js  c++  java
  • 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();
        }
    }
  • 相关阅读:
    我也要学C语言第十三章:复合数据类型—指针与指针变量(一)
    汇编语言程序设计学习笔记(第一遍学习)第1节:机器语言编程到汇编语言的产生
    汇编语言程序设计学习笔记(第一遍学习)第2节:寄存器
    我也要学C语言第十二章:编译预处理——带参数的宏
    PHP 清除HTML代码、空格、回车换行符的函数
    C#流程控制
    php引用(&)详解
    PHP defined() 函数
    PHP程序员最易犯10种错
    C# 函数
  • 原文地址:https://www.cnblogs.com/m2492565210/p/7250628.html
Copyright © 2011-2022 走看看