Java静态代理
示例代码
接口:
package com.ssg.aop.interfaces;public interface MathCalculator {
// 加法public int add(int a, int b);
}
接口实现类:
package com.ssg.aop.impl;
import com.ssg.aop.interfaces.MathCalculator;public class MathCalculatorImpl implements MathCalculator {@Overridepublic int add(int a, int b) {int i = a + b;System.out.println("方法执行结果 = " + i);return i;}
}
静态代理类:
- 静态代理类继承接口文件,重写方法
- 静态代理类通过构造器来引入原代理类。
package com.ssg.aop.proxy.statics;
import com.ssg.aop.interfaces.MathCalculator;public class MathCalculatorStaticProxy implements MathCalculator {// 接口倒置,注入接口,而不是实现类private MathCalculator mathCalculator;public MathCalculatorStaticProxy(MathCalculator mathCalculator) {this.mathCalculator = mathCalculator;}/*** @param a* @param b* @return*/@Overridepublic int add(int a, int b) {System.out.println("开始 >>> a + b == " + a + "+" + b);int add = mathCalculator.add(a, b);System.out.println("结束 >>> a + b = " + add);return add;}
}
@Test测试类
public class TestMathCalculator {@Testpublic void testAdd() {MathCalculator mathCalculatorImpl = new MathCalculatorImpl();MathCalculator calculator = new MathCalculatorStaticProxy(mathCalculatorImpl);int result = calculator.add(1, 2);System.out.println("Test add result = " + result);}
}
Java原生动态代理
Java原生动态代理,缺点是:代理对象必须是接口,没有接口无法代理。为所有方法进行代理,不能灵活操控。
示例代码
接口文件、接口实现类、动态代理类、Test类。
接口和接口实现类
沿用静态代理中的接口和接口实现类。
动态代理类:
写法一
核心:类加载器、类接口、InvocationHandler逻辑类其作用为:动态代理的具体逻辑代码写在该处。
Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h);
package com.ssg.aop.proxy.dynamic;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;public class MathCalculatorDynamicProxy {public static Object getDynamicProxy(Object object) {// object:目标对象,被代理的对象// 第一个参数:需要类加载器,通过反射获取// 第二个参数:需要获取类接口(被代理对象的接口)信息,通过反射// 第三个对象:代理逻辑,怎么去代理return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("动态代理执行前:" + Arrays.toString(args));Object invoke = method.invoke(object, args);System.out.println("动态代理执行后:" + invoke.toString());return invoke;}});}
}
写法二:
/*** 动态代理,代理所有类方法* @param mathClass 被代理的对象,数学计算器类* @return*/public static Object getProxyInstance(Object mathClass) {InvocationHandler invocationHandler = new InvocationHandler() {/*** @param proxy 代理* @param method 代理方法,被调用方法* @param args 代理方法的参数,被调用的参数* @return* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("动态代理执行前:" + Arrays.toString(args));Object invoke = method.invoke(mathClass, args);System.out.println("动态代理执行后:" + invoke.toString());return invoke;}};// 返回 动态代理类return Proxy.newProxyInstance(mathClass.getClass().getClassLoader(), mathClass.getClass().getInterfaces(), invocationHandler);};
@Test测试类:
package com.ssg.aop;import com.ssg.aop.impl.MathCalculatorImpl;
import com.ssg.aop.interfaces.MathCalculator;
import com.ssg.aop.proxy.dynamic.MathCalculatorDynamicProxy;
import org.junit.jupiter.api.Test;public class DynamicTest {@Testpublic void test() {MathCalculator mathCalculator = new MathCalculatorImpl();MathCalculator dynamicProxy = (MathCalculator) MathCalculatorDynamicProxy.getDynamicProxy(mathCalculator);int add = dynamicProxy.add(1, 2);System.out.println("测试方法执行结果为 = " + add);}
}
结果输出:
动态代理执行前:[1, 2]
方法执行结果 = 3
动态代理执行后:3
测试方法执行结果为 = 3