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

动态代理

时间:2024-02-16 20:44:05浏览次数:26  
标签:System 代理 public println 动态 method out

JDK动态代理

例子:

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

/**
 * @author Pickle
 * @version V1.0
 * @date 2024/2/16 17:25
 */


interface Calculator {
    void add();
    void sub();

}

class CalculatorImp implements Calculator {
    @Override
    public void add() {
        System.out.println("加法");
    }

    @Override
    public void sub() {
        System.out.println("减法");
    }
}

//计算代理类需要实现InvocationHandler接口,并且含有被代理类的对象
class CalculatorProxy implements InvocationHandler {

    private Object object;

    public CalculatorProxy(Object object){

        this.object = object;

    }

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        //method 与代理对象调用的方法对应
        System.out.println("计算前");
        method.invoke(object, objects);
        System.out.println("计算后");
        return null;
    }
}

public class JDKDynamicProxyDemo {
    public static void main(String[] args) {

        //定义被代理对象
        Calculator calculator = new CalculatorImp();

        final Calculator proxy = (Calculator) Proxy.newProxyInstance(
                calculator.getClass().getClassLoader(),
                calculator.getClass().getInterfaces(),
                new CalculatorProxy(calculator));

        proxy.sub();
        System.out.println("-----------");
        proxy.add();
    }
}

结果

计算前
减法
计算后
-----------
计算前
加法
计算后

总结:JDK动态代理最致命的缺点就是只能代理实现了接口的类,使用CGLIB动态代理可以解决这个问题

CGLIB动态代理

/**
 * 被代理类(无需实现接口)
 * @author Pickle
 * @version V1.0
 * @date 2024/2/16 20:17
 */
public class Calculator {

    public void sub() {

        System.out.println("sub");

    }

    public void add(){
        System.out.println("add");
    }
}

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * 自定义方法拦截器
 * @author Pickle
 * @version V1.0
 * @date 2024/2/16 20:18
 */
public class MyMethodInterceptor implements MethodInterceptor{
    /**
     * @param o             被代理的对象
     * @param method        被拦截的方法
     * @param objects       方法入参
     * @param methodProxy   用于调用原始方法
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        System.out.println("before method " + method.getName());

        methodProxy.invokeSuper(o, objects);

        System.out.println("after method " + method.getName());

        return objects;
    }
}

import net.sf.cglib.proxy.Enhancer;

/**
 * 代理类工厂
 * @author Pickle
 * @version V1.0
 * @date 2024/2/16 20:22
 */
public class CglibProxyFactory {

    /**
     * @param clazz     被增强类的class对象
     */
    public static Object getProperty(Class<?> clazz) {
        //创建动态代理增强类
        final Enhancer enhancer = new Enhancer();
        //设置类加载器
        enhancer.setClassLoader(clazz.getClassLoader());
        //设置被代理类
        enhancer.setSuperclass(clazz);
        //设置方法拦截器
        enhancer.setCallback(new MyMethodInterceptor());

        return enhancer.create();
    }

}

执行


public class execute {
    public static void main(String[] args) {
        final Calculator aliSmsServiceProxy = (Calculator) CglibProxyFactory.getProperty(Calculator.class);

        aliSmsServiceProxy.sub();

        System.out.println("----------------");

        aliSmsServiceProxy.add();
    }
}

结果

before method sub
sub
after method sub
----------------
before method add
add
after method add

标签:System,代理,public,println,动态,method,out
From: https://www.cnblogs.com/poteitoutou/p/18017428

相关文章

  • [Vite] 静态资源的动态访问
    前言这篇笔记是对渡一教育网课的知识点总结,源视频......
  • Qt环境Windows应用程序动态变更系统默认打印机
    有些工作环境安装有多个打印机,针对不同需求进行各种输出。如果是用QPrinter进行打印控制,可以通过setPrinterName确定使用哪一个打印机,但如果程序使用了第三方功能进行打印输出,比如通过QAxObject调用系统的文字处理直接输出,就可能会遇到无法明确指定哪一个打印机的问题。这时就需要......
  • 一维动态规划题目
    746.使用最小花费爬楼梯力扣题目链接思路:暴力递归解题思路把每一种可能都枚举,也就是dfs搜索每一种可能的情况,再求出其中最小的花费返回即可。代码实现//求两个数中的最小值intmin(inta,intb){returna<b?a:b;}//表示从下标i开始到costSize-1位置的......
  • 【算法】【动态规划】过桥问题
    1 题目在一个夜黑风高的晚上,有n(n<=50)个小朋友在桥的这边,现在他们需要过桥,但是由于桥很窄,每次只允许不大于两人通过,他们只有一个手电筒,所以每次过桥的两个人需要把手电筒带回来,i号小朋友过桥的时间为T[i],两个人过桥的总时间为二者中时间长者。问所有小朋友过桥的总时间最短是......
  • 动态规划基础笔记
    背包问题 01背包  一般的动态规划要先考虑好状态,这个状态是一个集合,要能分成几个子集,然后从这些子集(小问题),推到这一整个集合(大问题),且求解过程是一样的,就可以可以转换成大问题分解成小问题一个一个求解,最后合并先要知道状态表示什么再要知道dp的属性,应该跟所求有关,只会......
  • 动态规划题目合集
    3n多米诺问题\(dp[i]\)表示前\(i\)列的方案数,\(dp2[i]\)表示前\(i\)列但是最上面一行缺一个的方案数。\(dp[i],dp2[i]\)可以相互递推,而且刚好是矩阵递推。矩阵快速幂优化。Walk有向无权图。求长度\(k\)的路径条数。我们发现邻接矩阵的\(k\)次方各个元素求和就是......
  • vue 父传子 props 静态属性和动态属性
    Props静态属性<template> <div>   <ConpentA title="我是静态props"/> </div></template><script> importConpentAfrom'./components/ConpentA.vue' exportdefault{  components:{   ConpentA......
  • SQLSERVER:动态SQL
    --SqlServer动态Sql--动态SQL是指在运行时构造并执行的sql语句。这种技术在sqlserver中非常有用,尤其--是在需要编写灵活且可适应不同情况的代码时。动态sql可以用来创建通用的存储过程,--执行复杂的查询或者在运行时根据特定条件构建SQL语句。--优势与风险:--动态SQL的主要优势......
  • 【题单】一个动态更新的洛谷综合题单
    洛谷试炼场的题目确实很具有代表性,但是近几年以来,又有许多经典题目出现在OI界中,这个大题单就是作为洛谷试炼场的扩展和补充。目录新版本食用指南更新日志题单Part0试机题Part1入门阶段Part2基础算法Part3搜索Part4动态规划Part4.1-4.4动态规划Part4.5-4.12动态规......
  • 【算法】【动态规划】钢条切割
    1 题目来自算法导论的一道经典题目:2 解答动态规划原理虽然已经用动态规划方法解决了上面问题,但是大家可能还跟我一样并不知道什么时候要用到动态规划。总结一下上面的斐波拉契数列和钢条切割问题,发现两个问题都涉及到了重叠子问题,和最优子结构。①最优子结构用动态规......