Java静态代理
示例代码
接口:
java
package com.ssg.aop.interfaces;
public interface MathCalculator {
// 加法
public int add(int a, int b);
}
接口实现类:
java
package com.ssg.aop.impl;
import com.ssg.aop.interfaces.MathCalculator;
public class MathCalculatorImpl implements MathCalculator {
@Override
public int add(int a, int b) {
int i = a + b;
System.out.println("方法执行结果 = " + i);
return i;
}
}
静态代理类:
- 静态代理类继承接口文件,重写方法
- 静态代理类通过构造器来引入原代理类。
java
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
*/
@Override
public 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测试类
java
public class TestMathCalculator {
@Test
public 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);
java
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() {
@Override
public 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;
}
}
);
}
}
写法二:
java
/**
* 动态代理,代理所有类方法
* @param mathClass 被代理的对象,数学计算器类
* @return
*/
public static Object getProxyInstance(Object mathClass) {
InvocationHandler invocationHandler = new InvocationHandler() {
/**
* @param proxy 代理
* @param method 代理方法,被调用方法
* @param args 代理方法的参数,被调用的参数
* @return
* @throws Throwable
*/
@Override
public 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测试类:
java
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 {
@Test
public 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