定义
代理模式一般分为静态代理和动态代理两种:
- 静态代理,顾名思义,就是提前创建好代理类文件并在程序运行前已经编译成字节码。
- 动态代理,是指在运行时动态生成代理类,即代理类的字节码将在运行时生成并载入到ClassLoader中。
静态代理实现
#### 1、接口 类
public interface ISender {
public boolean send();
}
#### 2、实现类
public class SmsSender implements ISender {
public boolean send() {
System.out.println("sending msg");
return true;
}
}
#### 3、静态代理
public class ProxySender implements ISender {
private ISender sender;
public ProxySender(ISender sender){
this.sender = sender;
}
public boolean send() {
System.out.println("处理前");
boolean result = sender.send();
System.out.println("处理后");
return result;
}
}
#### 4、客户端调用
@Test
public void testStaticProxy(){
ISender sender = new ProxySender(new SmsSender());
boolean result = sender.send();
System.out.println("输出结果:" + result);
}
动态代理实现
与静态代理相比,动态代理有更多优势,动态代理不仅不需要定义代理类,甚至可以在运行时指定代理类的执行逻辑,从而大大提升系统的灵活性。
jdk
JDK的动态代理需要实现一个处理方法调用的Handler,用于实现代理方法的内部逻辑,实现InvocationHandler接口。
#### 动态代理类
public class JdkProxyHandler implements InvocationHandler {
private Object target;
public JdkProxyHandler(Object target){
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("处理前");
Object result = method.invoke(target,args);
System.out.println("处理后");
return result;
}
}
####4、客户端调用
@Test
public void testJdkProxy(){
ISender sender = (ISender) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
new Class[]{ISender.class},
new JdkProxyHandler(new SmsSender()));
boolean result = sender.send();
System.out.println("代理对象:" + sender.getClass().getName());
System.out.println("输出结果:" + result);
}
JDK的动态代理底层是通过Java反射机制实现的,并且需要目标对象继承自一个接口才能生成它的代理类。
CGLIB
CGLIB:Code Generation Library动态代理
使用CGLIB动态代理前需要引入依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
和JDK代理不同,CGLib动态代理技术不需要目标对象实现自一个接口,只需要实现一个处理代理逻辑的切入类,并实现MethodInterceptor接口。
public class BdSender {
public boolean send() {
System.out.println("sending msg");
return true;
}
}
代理类逻辑处理类:
public class CglibProxyInterceptor implements MethodInterceptor {
private Enhancer enhancer = new Enhancer();
/**
* 获取代理类
* @param clazz
* @return
*/
public Object getProxy(Class clazz) {
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("处理前");
Object result = methodProxy.invokeSuper(object,args);
System.out.println("处理后");
return result;
}
}
客户端调用
@Test
public void testCglibProxy(){
BdSender sender = (BdSender) new CglibProxyInterceptor().getProxy(BdSender.class);
boolean result = sender.send();
System.out.println("代理对象:" + sender.getClass().getName());
System.out.println("输出结果:" + result);
}