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

    代理模式

      

      代理类和委托类有相同的接口,一个代理类的的对象与一个委托类的对象关联。代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法来提供特定的服务。代理类就像是明星,委托类就像是经纪人。关于代理模式的原理,不做过多的介绍,网上有很多帖子,本文主要侧重于代码的实现。

      

      静态代理:

      因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.

      

      动态代理:

      动态代理分为两类,一类是JDK动态代理,主要针对实现接口的情况,另一类是cglib动态代理,主要是对指定的类生成一个子类

      1. JDK动态代理

      proxy 类:类的静态方法用来生成动态代理的实例

      innovationhandler 接口有一个 invoke 方法,用来集中处理在动态代理类对象的方法调用,通常在该方法中实现对委托类的代理访问,每次生成动态代理对象时都要指定一个对应的调用处理器。

    接口:

    package com.commonCode.DynamicProxy;
    
    /**
     * Created by Demrystv.
     */
    
    /**
     * 接口
     */
    public interface UserService {
    
        public void addUser();
    
        public void updateUser();
    
        public void delUser();
    
    }

    目标类:

    package com.commonCode.DynamicProxy;
    
    /**
     * Created by Demrystv.
     */
    
    /**
     * 目标类
     */
    public class UserServiceImpl implements UserService {
        @Override
        public void addUser() {
            System.out.println("添加用户");
        }
    
        @Override
        public void updateUser() {
            System.out.println("更新用户");
        }
    
        @Override
        public void delUser() {
            System.out.println("删除用户");
        }
    }

    JDK动态代理类:

    package com.commonCode.DynamicProxy;
    
    /**
     * Created by Demrystv.
     */
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * 代理类,JDK动态代理,针对实现接口的情况
     * 需要在springContext.xml中增加如下配置:
     * <aop:aspectj-autoproxy proxy-target-class="true"/>
     */
    public class MyBeanFacByJDK {
        public static UserService createUserService(){
    
            //目标类
            final UserService userService = new UserServiceImpl();
            //生成代理类
            UserService proxyService = (UserService) Proxy.newProxyInstance(MyBeanFacByJDK.class.getClassLoader(),
                    UserService.class.getInterfaces(), new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            System.out.println("执行前");
                            Object obj = method.invoke(userService, args);
                            System.out.println("执行后");
                            System.out.println("===================");
                            return obj;
                        }
                    });
            return proxyService;
        }
    }

      2. cglib动态代理

      CGlib 是针对类来实现代理,他的原理是对指定的目标类生成一个子类,并且覆盖其中方法实现增强,因为采用的是继承,所以不能对 final 修饰的类进行代理, methodinterceptor。

    package com.commonCode.DynamicProxy;
    
    /**
     * Created by Demrystv.
     */
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    /**
     * 代理类,cglib动态代理,针对没有实现接口的情况,对指定的类生成一个子类
     */
    public class MyBeanFacByCglib {
    
        public static UserService createUserService(){
            //目标类
            final UserService userService = new UserServiceImpl();
    
            //生成代理类
            //1.核心类
            Enhancer enhancer = new Enhancer();
            //2.确定父类
            enhancer.setSuperclass(UserService.class);
            //3.设置回调函数
            enhancer.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)
                        throws Throwable {
                    System.out.println("执行前");
                    Object obj = method.invoke(userService, objects);
                    System.out.println("执行后");
                    System.out.println("==================");
                    return obj;
                }
            });
            //4.创建代理对象
            UserService proxyUserService = (UserService) enhancer.create();
            return proxyUserService;
        }
    }

      

  • 相关阅读:
    MySQL视图——学习笔记及实验
    小学生四则运算自动刷题库优化升级
    软件工程小项目——小学生四则运算自动刷题库
    笔记--运算符、表达式和语句
    笔记--基本数据类型与数组
    笔记--java入门
    原因: java.lang.ClassNotFoundException: Hello
    使用gopm代替go get 解决go包卡慢的问题
    调用微信截图功能c# 截图带扩展名
    如何用golang搜索抓取淘宝商品
  • 原文地址:https://www.cnblogs.com/Demrystv/p/9420699.html
Copyright © 2011-2022 走看看