zoukankan      html  css  js  c++  java
  • AOP-动态代理

    动态代理的原理
    代理设计模式的原理:使用一个代理将原本对象包装起来,然后用该代理对象”取代”原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。

    代理模式:可以理解为有两个对象,代理对象和目标对象,代理对象就是帮助我们完成这件事的对象,目标对象就是我们要去做的事情。动态代理就是无论目标对象是什么,都可以通过这样的一个类,去动态生成相对应的代理对象,帮助去完成相应的功能。更像是一个工具类,在任何情况下去生成一个代理对象。

    代理对象生成以后,为什么也能帮助我们去实现最终的功能?

    ①代理对象知道要实现什么功能。②代理对象对接口中的抽象方法的实现,可以利用InvocationHandler来控制代理对象对功能的实现过程。

    动态代理的方式
      1) 基于接口实现动态代理: JDK动态代理
      2) 基于继承实现动态代理: Cglib、Javassist动态代理

    package com.atguigu.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyUtil {
    
        private MathImpl mathImpl;//目标对象,其实应该是Object
        
        public Object getProxy() {
            ClassLoader loader = this.getClass().getClassLoader();//类的加载器,创建一个代理类,动态生成一个动态代理类,执行就需要加载,需要指定一个类加载器
            Class[] interfaces = mathImpl.getClass().getInterfaces();//目标对象都有那些方法,代理对象通过获取其实现的接口确定,所以代理对象会和目标对象一样实现相同的接口
            return Proxy.newProxyInstance(loader, interfaces, new InvocationHandler() {//第三个参数:代理对象如何实现目标对象的方法
                //Java中的所有生成的动态代理类都继承于Proxy类
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    return method.invoke(mathImpl, args);//代理模式原则要保证结果的一致性,可以让代理对象调用目标对象的方法就可以保证一致性
                }
            });
        }
        
    }

    实现对计算器的动态代理:

    package com.atguigu.proxy;
    
    import java.util.Properties;
    
    public class Test {
    
        public static void main(String[] args) {
            
            /*MathI math = new MathImpl();
            int result = math.div(1, 1);
            System.out.println(result);*/
            
            ProxyUtil proxy = new ProxyUtil(new MathImpl());
            MathI math = (MathI)proxy.getProxy();  //注意不能使用目标对象类型,因为目标类可能还有接口标准之外的方法,所以要强转为接口变量引用
            int i = math.div(4, 1);
            System.out.println(i);
            
        }
        
    }
    package com.atguigu.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.util.Arrays;
    
    public class ProxyUtil {
    
        private MathImpl mathImpl;   //实际中采用Object类型
        
        
        
        public ProxyUtil(MathImpl mathImpl) {
            super();
            this.mathImpl = mathImpl;
        }
    
    
    
        public Object getProxy() {
            //获取当前类的类加载器,用来加载代理对象所属类
            ClassLoader loader = this.getClass().getClassLoader();
            //获取目标对象实现的所有接口的Class,代理类回合目标类实现相同的接口,最终通过代理对象实现功能
            Class[] interfaces = mathImpl.getClass().getInterfaces();
                    
            return Proxy.newProxyInstance(loader, interfaces, new InvocationHandler() {
                
                //代理对象实现功能的方式
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    // TODO Auto-generated method stub
                    try {
                        MyLogger.before(method.getName(), Arrays.toString(args));
                        Object result = method.invoke(mathImpl, args);//动态代理对象实现功能
                        MyLogger.after(method.getName(), result);
                        return result;
                    } catch (Exception e) {
                        // TODO: handle exception
                        MyLogger.throwing();
                        e.printStackTrace();
                    } finally {
                        System.out.println("哪都有我");
                    }
                    return null;
                }
            });
        }
        
    }
    package com.atguigu.proxy;
    
    public interface MathI {
    
        int add(int i, int j);
        int sub(int i, int j);
        int mul(int i, int j);
        int div(int i, int j);
        
    }
    interface MathI
    package com.atguigu.proxy;
    
    public class MathImpl implements MathI {
    
        @Override
        public int add(int i, int j) {
            int result = i + j;
            return result;
        }
    
        @Override
        public int sub(int i, int j) {
            int result = i - j;
            return result;
        }
    
        @Override
        public int mul(int i, int j) {
            int result = i * j;
            return result;
        }
    
        @Override
        public int div(int i, int j) {
            int result = i / j;
            return result;
        }
    
        
        
    }
    MathImpl
    package com.atguigu.proxy;
    
    public class MyLogger {
    
        public static void before(String methodName, String args) {
            System.out.println("method:"+methodName+",arguments:"+args);
        }
        
        public static void after(String methodName, Object reslut) {
            System.out.println("method:"+methodName+",reslut:"+reslut);
        }
        
        public static void throwing() {
            System.out.println("有异常了。。。。");
        }
        
    }
    MyLogger
  • 相关阅读:
    集合类说明及区别
    Liferay
    ASP项目部署IIS7.5中遇到的问题
    IBM X3650 M3/M4的服务器装系统
    在table中tr的display:block在firefox下显示布局错乱问题
    Firefox table 不居中解决办法 解决火狐层或 table 不居中
    Java进阶: File类的特点?如何创建File类对象?Java中如何操作文件内容,什么是Io流Io流如何读取和写入文件?字节缓冲流使用原则?
    计算机期末考试高频考试题目,附带题目解析
    java基础使用的集合大总结
    TreeMap集合根据指定元素,进行删除和修改bug梳理
  • 原文地址:https://www.cnblogs.com/lemonzhang/p/12907886.html
Copyright © 2011-2022 走看看