两种动态代理
前言
看到代理模式的时候,顺便搜索了下动态代码的两种实现。
这里顺手记录下
一、jdk动态代理
1.接口和实现类
public interface Service {
void reduceStock();
}
public class ServiceImpl implements Service {
@Override
public void reduceStock() {
System.out.println("实现类中...输出");
}
}
2.代理类proxy
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxy implements InvocationHandler {
private final Object object;
public DynamicProxy(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("日志开始");
Object invoke = method.invoke(object, args);
System.out.println("日志结束");
return invoke;
}
}
3.测试类
import java.lang.reflect.Proxy;
public class JdkProxyDemo {
public static void main(String[] args) {
//实现了接口的业务类
ServiceImpl iService = new ServiceImpl();
//获取Class对象
Class<?> iServiceClass = iService.getClass();
//代理类 实现需要实现InvocationHandler接口,重写invoke方法 传入业务实现类对象
DynamicProxy dynamicproxy = new DynamicProxy(iService);
//创建代理类对象
Service so = (Service) Proxy.newProxyInstance(iServiceClass.getClassLoader(), iServiceClass.getInterfaces(), dynamicproxy);
so.reduceStock();
}
}
4.输出
日志开始
实现类中...输出
日志结束
二、cglib实现
1.引入库
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.7</version>
</dependency>
2.接口和实现类
public interface UserService {
public void say();
public void say2();
}
public class UserServiceImpl implements UserService{
@Override
public void say() {
System.out.println("hello");
say2();
}
@Override
public void say2() {
System.out.println("hello2");
}
public final void finalMethod() {
System.out.println("final method");
}
public static void staticMethod() {
System.out.println("static method");
}
}
3.代理类proxy
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MyInterceptor implements MethodInterceptor {
private Object target;
public MyInterceptor(Object target) {
this.target = target;
}
/**
*
* @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("cglib before");
// 调用代理类FastClass对象
// Object result = methodProxy.invokeSuper(o, objects);
Object result = methodProxy.invoke(target, objects);
System.out.println("cglib after");
return result;
}
}
4.测试类
import net.sf.cglib.proxy.Enhancer;
public class CglibDemo {
public static void main(String[] args) {
UserServiceImpl target = new UserServiceImpl();
// 代理类class文件存入本地磁盘方便我们反编译查看源码
// System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "./code");
// 通过CGLIB动态代理获取代理对象的过程
Enhancer enhancer = new Enhancer();
// 设置enhancer对象的父类
enhancer.setSuperclass(UserServiceImpl.class);
// 设置enhancer的回调对象
enhancer.setCallback(new MyInterceptor(target));
// 创建代理对象
UserServiceImpl userService = (UserServiceImpl)enhancer.create();
// 通过代理对象调用目标方法
userService.say();
userService.finalMethod();
UserServiceImpl.staticMethod();
}
}
5.输出结果
cglib before
hello
hello2
cglib after
final method
static method
总结
代理模式中的静态代理,几乎没啥实用价值。
AOP(切面)其底层就是实用的JDK动态代理。
效率比较:cglib动态代理更快