首页 > 其他分享 >spring动态代理

spring动态代理

时间:2023-02-12 21:44:52浏览次数:41  
标签:spring Object 代理 -------------------- user 动态 public targetObject

动态代理

public interface UserManager {
    void addUser(String username);
    void delUser(String username);
}
public class UserManagerImpl implements UserManager {

    @Override
    public void addUser(String username) {
        System.out.println("add user " + username);
    }

    @Override
    public void delUser(String username) {
        System.out.println("delete user " + username);
    }
}

JDK动态代理

package wang.proxy.jdkproxy;

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

public class JDKProxy implements InvocationHandler {
    // 用于指向被代理对象
    private Object targetObject;

    public Object newProxy(Object targetObject) {
        // 将被代理对象传入进行代理
        this.targetObject = targetObject;
        // 返回代理对象
        return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(), this.targetObject.getClass().getInterfaces(), this);
    }

    /**
     * 被代理对象的任何方法执行时,都会被invoke方法替换,即:代理对象执行被代理对象中的任何方法时,实际上执行的时当前的invoke方法
     *
     * @param proxy(代理对象的引用)
     * @param method(当前执行的方法)
     * @param args(当前执行方法所需的参数)
     * @throws Throwable
     * @return(和被代理对象方法有相同的返回值)
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 在原来的方法上增加了日志打印功能,增强代码
        printLog(method.getName());

        return method.invoke(targetObject, args);
    }

    /**
     * 模拟日志打印
     */
    private void printLog(String methodName) {
        System.out.println("日志打印: " + methodName);
    }
}

测试:

public class JDKMain {
    public static void main(String[] args) {
        UserManager userManager = new UserManagerImpl();
        System.out.println("--------------------没有使用增强过的方法--------------------");
        userManager.addUser("root");
        userManager.delUser("root");

        System.out.println("--------------------使用代理对象增强过的方法--------------------");
        JDKProxy jdkProxy = new JDKProxy();
        UserManager userManagerProxy = (UserManager)jdkProxy.newProxy(userManager);
        userManagerProxy.addUser("scott");
        userManagerProxy.delUser("scott");
    }
}

--------------------没有使用增强过的方法--------------------
add user root
delete user root
--------------------使用代理对象增强过的方法--------------------
日志打印: addUser
add user scott
日志打印: delUser
delete user scott

CGLIB动态代理

public class CGLibProxy implements MethodInterceptor {
    // 用于指向被代理对象
    private Object targetObject;

    // 用于创建代理对象
    public Object createProxy(Object targetObject) {
        this.targetObject = targetObject;
        return new Enhancer().create(this.targetObject.getClass(), this);
    }

    /**
     * @param proxy(代理对象的引用)
     * @param method(当前执行的方法)
     * @param args(当前执行方法所需的参数)
     * @param methodProxy(当前执行方法的代理对象)
     * @throws Throwable
     * @return(和被代理对象方法有相同的返回值)
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        String methodName = method.getName();
        if ("addUser".equals(methodName)) {
            printLog(methodName);
        }
        System.out.println("xx:" + methodProxy.getSuperName());
        return methodProxy.invokeSuper(proxy, args);
    }

    /**
     * 模拟日志打印
     */
    /**
     * 模拟日志打印
     */
    private void printLog(String methodName) {
        System.out.println("日志打印: " + methodName);
    }
}

测试

public class CGLIBMain {
    public static void main(String[] args) {
        UserManager userManager = new UserManagerImpl();
        System.out.println("--------------------没有使用增强过的方法--------------------");
        userManager.addUser("root");
        userManager.delUser("root");

        System.out.println("--------------------使用代理对象增强过的方法--------------------");
        CGLibProxy cgLibProxy = new CGLibProxy();
        UserManager cgLibProxyProxy = (UserManager)cgLibProxy.createProxy(userManager);
        cgLibProxyProxy.addUser("scott");
        cgLibProxyProxy.delUser("scott");
    }
}
--------------------没有使用增强过的方法--------------------
add user root
delete user root
--------------------使用代理对象增强过的方法--------------------
日志打印: addUser
xx:CGLIB$addUser$0
add user scott
xx:CGLIB$delUser$1
delete user scott

标签:spring,Object,代理,--------------------,user,动态,public,targetObject
From: https://www.cnblogs.com/shmilyt/p/17114775.html

相关文章

  • 五.注解配置SpringMVC
    使用配置类和注解代替web.xml和SpringMVC配置文件的功能1、创建初始化类,代替web.xml在Servlet3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerlnitialize......
  • springboot 多数据源 实例(sybase、mysql数据库)(下)
    接下来见证奇迹的时刻:首先要借鉴yandype这位大神的总结的代码:说明:springboot2.3.x+mybatisplus+ druid +sybase+mysql多数据源整合1、项目依赖<?xmlvers......
  • day07-SpringMVC底层机制简单实现-03
    SpringMVC底层机制简单实现-03https://github.com/liyuelian/springmvc-demo.git7.任务6-完成控制器方法获取参数-@RequestParam功能说明:自定义@RequestParam注解和......
  • Spring+MyBatis整合步骤
    一、两者整合的主要工作:把MyBatis框架中使用到的核心对象(组件)配置到Spring中,交给Spring来创建管理;具体来说:将MyBatis匹配文件中的数据源、SQL映射文件、SqlSessionFactoryBu......
  • springboot 多数据源 实例(sybase、mysql数据库)(上)
    最近项目需要用到sybase(sqlanywhere)、mysql数据库两边数据交互。由于之前对sybase数据库一点不懂踩了许多坑特意记下:连接sybase客户端需要用到 SQLCentral1......
  • 动态规划——从入门到入土
    什么是动态规划?动态规划,英文名为DynamicProgramming,又称DP(当然小写的dp也行),是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。由于动态规划并不是某......
  • SpringMVC源码(三):九大内置组件初始化
    在源码(二):MVC容器启动的分析中,MVC容器刷新完成后,通过发布事件及事件监听处理器来初始化MVC的九大组件,下面来分析下这九大组件初始化的细节。概览初始化MVC组件,D......
  • OpenEBS动态创建存储
    简介​​OpenEBS​​是一种开源云原生存储解决方案,托管于​​CNCF​​基金会,目前该项目处于沙箱阶段,​​OpenEBS​​是一组存储引擎,允许您为有状态工作负载(​​StatefulSet......
  • Spring框架基础知识
    SpringSpringFrameworkIOC技术(InversionofControl)核心思想使用对象时,不要主动使用new产生对象,而是由外部提供对象。对象的控制权由程序转移到外部,称为控制反转,就......
  • SpringBoot 时间格式化的 5 种实现方法!
    在我们日常工作中,时间格式化是一件经常遇到的事儿,所以本文我们就来盘点一下SpringBoot中时间格式化的几种方法。时间问题演示为了方便演示,我写了一个简单SpringBoot......