Proxy > 基于接口和基于子类的两种动态代理

> 基于接口

1.1 编写一个接口及其接口的实现类

public interface ParentClass {
    
    
   void showAccount(Float money); // 显示账户
   void saveMoney(Float money); // 保存钱
}
public class ParentClassImpl implements ParentClass{
    
    
    @Override
    public void showAccount(Float money) {
    
    
    	// 显示账户方法中并未使用形参
        System.out.println("This is showAccount !!");
    }

    @Override
    public void saveMoney(Float money) {
    
    
	    // 保存钱的方法中并未使用形参
        System.out.println("This is saveMoney !!");
    }
}

1.2 基于接口的代理对方法中形参的值进行增强

1.2.1 未增强之前

public class MainDome{
    
    
    public static void main(String[] args) {
    
    
        ParentClassImpl parentClass = new ParentClassImpl();
        parentClass.showAccount(100000f);
        parentClass.saveMoney(1200f);
    }
}

执行结果

在这里插入图片描述

1.2.2 增强之后

public class MainDome{
    
    
    public static void main(String[] args) {
    
    
        ParentClassImpl parentClass = new ParentClassImpl();

        Object o = Proxy.newProxyInstance(parentClass.getClass().getClassLoader(),
         parentClass.getClass().getInterfaces(), new InvocationHandler() {
    
    
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
				// proxy :代理对象的引用
				// method :当前执行的方法
				// args :执行当前方法所需加载的参数

                // 获取返回的值
                Object returnValue = null;
                Float money = (Float) args[0];

                // 当方法为showAccount时
                if ("showAccount".contains(method.getName())) {
    
    
                    if (money < 10000f) System.out.println("001  !!");
                    else System.out.println("有钱人 001 !!");
                    returnValue = method.invoke(parentClass, args[0]);
                }

                // 当方法为showAccount时
                if ("saveMoney".contains(method.getName())) {
    
    
                    if (money < 10000f) System.out.println("002  !!");
                    else System.out.println("有钱人 002 !!");
                    returnValue = method.invoke(parentClass, args[0]);
                }

                return returnValue;
            }
        });
        ParentClass p = (ParentClass) o;
        p.showAccount(1000f);
        p.saveMoney(12000f);
    }
}

由于匿名内部类中只有一个 invoke 方法,所以可以简写为 lambda 表达式

Object o = Proxy.newProxyInstance(parentClass.getClass().getClassLoader(), parentClass.getClass().getInterfaces(),
    (proxy,method,arg)->{
    
    
        // 获取返回的值
        Object returnValue = null;
        Float money = null;

        // 对参数值进行判断,判断参数是否为float类型
        if (arg[0].getClass().getTypeName().contains("Float")){
    
    
            // 由于增强方法内只有一个参数,这里就直接写了0下标
            money = (Float) arg[0];
        }else {
    
    
            throw new Exception("Input argument Exception !! This not float type !!");
        }

        // 当方法为showAccount时
        if ("showAccount".contains(method.getName())) {
    
    
            if (money < 10000f) System.out.println("001  !!");
            else System.out.println("有钱人 001 !!");
            returnValue = method.invoke(parentClass, arg[0]);
        }

        // 当方法为showAccount时
        if ("saveMoney".contains(method.getName())) {
    
    
            if (money < 10000f) System.out.println("002  !!");
            else System.out.println("有钱人 002 !!");
            returnValue = method.invoke(parentClass, arg[0]);
        }

        return returnValue;
    }
);

执行结果

在这里插入图片描述

> 基于实体类(本次测试需要借助cglib)

pom依赖注入

	<dependencies>
        <!-- https://mvnrepository.com/artifact/cglib/cglib -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency>
    </dependencies>

2.1 > 编写实体类

public class ParentClassImpl{
    
    
	// 当前并没有对形参有任何操作
    public void showAccount(Float money) {
    
    
        System.out.println("This is showAccount !!");
    }

    public void saveMoney(Float money) {
    
    
        System.out.println("This is saveMoney !!");
    }
}

2.1.1 > 未增强之前

在这里插入图片描述

2.1.1 > 增强之后

public class MainDome{
    
    
    public static void main(String[] args) {
    
    
    	// 创建一个实体类对象
        ParentClassImpl parentClass = new ParentClassImpl();

        ParentClassImpl parentClass1 = (ParentClassImpl) 
        Enhancer.create(parentClass.getClass(), new MethodInterceptor() {
    
    
            @Override
            public Object intercept(Object o, Method method, Object[] objects,
             MethodProxy methodProxy) throws Throwable {
    
    
                Object returnValue = null;
                Float argument = null;

                // is float type
                System.out.println(objects[0].getClass().getTypeName());
                if (objects[0].getClass().getTypeName().contains("Float")) argument = (Float) objects[0];
                else argument = null;

                // get method name
                if ("showAccount".contains(method.getName())) {
    
    
                    // yes , Name is 'showAccount' to this method
                    // Enhance This method
                    System.out.println("Money is : " + argument);
                }
                if ("saveMoney".contains(method.getName())) {
    
    
                    System.out.println("Save money is : " + argument);
                }

                return method.invoke(parentClass, objects[0]);
            }
        });

        parentClass1.showAccount(1200f);
        parentClass1.saveMoney(200f);
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43309893/article/details/119698838
今日推荐