zoukankan      html  css  js  c++  java
  • 代理模式

    AOP实现原理是基于动态代理实现的。

    代理模式是一种软件设计模式。其核心思想是通过访问代理对象去操作被代理的对象。代理对象与被代理对象有同样的方法接口,且对被代理的对象的方法进行了扩展。从而实现不修改被代理对象的情况下,实现被代理对象业务逻辑的更改。

    代理模式又分为静态代理和动态代理两种。

    我的目录为:

    一、静态代理是在代码编译是就确定了被代理对象。

    实现方式:

    1) 代理对象与被代理对象实现同样的接口==>保证行为一致与类型一致

    2) 代理对象持有一个被代理对象。==>代理对象能够调用被代理对象的逻辑

    a、Star.java文件

    /**
     * 代理类与被代理类实现统一的接口
     */
    public interface Star {
        void actor();
        void sing();
    }

    b、被代理对象LiuDenHua实现接口中的方法;

    public class LiuDenHua implements Star{
        @Override
        public void actor() {
            System.out.println("刘德华演戏");
        }
    
        @Override
        public void sing() {
            System.out.println("刘德华唱歌");
        }
    }

    c、代理类去实现接口,并添加一些其他的业务方法;

    /**
     * 代理类
     */
    public class StarProxy implements Star{
        //持有一个被代理对象
        private Star liuDenHua;//接口
        //private LiuDenHua liuDenHua;
        public StarProxy(Star liuDenHua) {
            this.liuDenHua = liuDenHua;
        }
        @Override
        public void actor() {
            System.out.println("经纪人谈合同");
            liuDenHua.actor();
            System.out.println("经纪人收钱");
        }
        @Override
        public void sing() {
            System.out.println("经纪人联系场地");
            liuDenHua.sing();
            System.out.println("经纪人收钱");
        }
    }

    d、写一个测试文件,测试是否成功;

    public class Test {
        public static void main(String[] args) {
            //创建被代理对象
            Star liuDenHua = new LiuDenHua();
            //创建代理对象,并传入被代理对象
            Star starProxy = new StarProxy(liuDenHua);
    // starProxy.actor();
    // starProxy.sing();
    show(starProxy); }
    public static void show(Star star){
    star.actor();
    star.sing();
    }
    }

    测试结果为:

    二、动态代理:在代码运行期间才加载被代理的类,动态生成代理对象。

    Spring 动态代理有两种实现机制
    1)JDK动态代理:jdk动态代理有java自身提供,其利用反射机制生成一个实现代理接口的匿名类(代理类)。Spring默认的方式。

    a、 被代理的类需要实现接口。

    b、接口

    c、被代理类

    d、生成代理对象的类 (实现InvocationHandler接口)

    /**
     * 动态代理
     * jdk代理
     * 实现InvocationHandler
     */
    public class JDKDynamicProxy implements InvocationHandler {
        //持有一个被代理对象
        private Object object;
    
        /**
         * 根据被代理对象生成代理类
         * @param targetObject  被代理的对象
         * @return
         */
        public Object getInstance(Object targetObject){
            //给被代理对象赋值
            this.object=targetObject;
            //生成代理对象
            return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),//获取类加载器
                    targetObject.getClass().getInterfaces(),//获取被代理对象实现的接口
                    this//动态代理方法执行时,会调用该对象的invoke方法
            );
        }
    
        /**
         * 调用代理对象的方法
         * @param proxy 代理对象
         * @param method  调用的方法
         * @param args  调用方法传递的参数
         * @return
         * @throws Throwable
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("开启事务");
            //调用被代理对象的方法
            Object invoke = method.invoke(object, args);
            System.out.println("提交事务");
            return invoke;
        }
    }

    测试:

    public class Test {
    
        public static void main(String[] args) {
            //被代理类
            LiuDenHua liuDenHua = new LiuDenHua();
            JDKDynamicProxy jdkDynamicProxy = new JDKDynamicProxy();
            //动态生成代理类对象
            Star instance = (Star) jdkDynamicProxy.getInstance(liuDenHua);
            instance.sing();
            instance.actor();
        }
    }

    2)cglib动态代理:通过java字节码编辑技术,生成一个被代理对象的一个子类(代理类)。来实现代理效果。

    a.        被代理的类不需要实现接口

    b.       被代理类(普通类)

    c.        生成代理对象类(实现MethodInterceptor接口)

    /**
     * cglib 动态代理
     */
    public class CglibDynamicProxy implements MethodInterceptor {
        /**
         * 生成代理对象的方法
         * @param target
         * @return
         */
        public Object getProxy(Object target){
            return Enhancer.create(target.getClass(),this);
        }
    
        /**
         *
         * @param o  被代理的对象
         * @param method  被代理的方法
         * @param objects  方法参数
         * @param methodProxy  代理方法
         * @return
         * @throws Throwable
         */
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("前置处理");
            //调用被代理对象的方法
            Object invoke = methodProxy.invokeSuper(o, objects);
            System.out.println("后置处理");
            return null;
        }
    }

    另外建一个Player.java文件:

    /**
     * 普通类
     */
    public class Player {
    
        public void play(){
            System.out.println("玩的很开心");
        }
    }

    测试:

     //cglib动态代理
            //创建被代理对象
            Player player = new Player();
            //创建生产动态代理对象的对象
            CglibDynamicProxy cglibDynamicProxy = new CglibDynamicProxy();
            //生产代理对象
            Player proxy = (Player) cglibDynamicProxy.getProxy(player);
            proxy.play();
  • 相关阅读:
    selenium-web自动化,常用api
    jmeter利用bean shell加密解密方法
    http请求属性说明(基础篇)
    移动端候选人面试要点
    CssSelector定位详解
    下载zip文件
    BeanShell生成随机中文字符
    BeanShell生成随机字符
    CentOS 7.2安装Oracle19C
    Centos7.4部署onlyoffice文档在线编辑服务器
  • 原文地址:https://www.cnblogs.com/xie-qi/p/13040736.html
Copyright © 2011-2022 走看看