代理模式
代理模式是Java常见的设计模式之一。所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象。
为什么要采用这种间接的形式来调用对象呢?一般是因为客户端不想直接访问实际的对象,或者访问实际的对象存在困难,因此通过一个代理对象来完成间接的访问。
静态代理
//定义发送短信接口
public interface SendMsgService {
public void send();
}
//接口实现类
@Slf4j
public class SendMsgImpl implements SendMsgService {
@Override
public void send() {
log.info("中国移动发短信!!!");
}
}
//代理实现类
@Slf4j
public class ProxySendMsgImpl implements SendMsgService {
private SendMsgService sendMsgService;
public ProxySendMsgImpl(SendMsgService sendMsgService) {
this.sendMsgService = sendMsgService;
}
@Override
public void send() {
log.info("发短信之前xxxx");
sendMsgService.send();
log.info("发短信之后xxxx");
}
}
/**
* 静态代理 测试
*/
@Test
public void test1() {
SendMsgService sendMsgService = new SendMsgImpl();
SendMsgService proxySendMsg = new ProxySendMsgImpl(sendMsgService);
proxySendMsg.send();
}
测试结果
动态代理
相比于静态代理来说,动态代理更加灵活。我们不需要针对每个目标类都单独创建一个代理类,并且也不需要我们必须实现接口,我们可以直接代理实现类( CGLIB 动态代理机制)。
JDK 动态代理机制
//定义接口
public interface SendMsgService2 {
public void send();
}
//接口实现类
@Slf4j
public class SendMsgImpl2 implements SendMsgService2 {
@Override
public void send() {
log.info("中国移动发短信!!!");
}
}
//InvocationHandler 实现类
@Slf4j
public class DebugInvocationHandler implements InvocationHandler {
/**
* 代理类中的真实对象
*/
private final Object target;
public DebugInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log.info("发送短信 前 jdkProxy。。。");
Object result = method.invoke(target, args);
log.info("发送短信 后 jdkProxy。。。");
return result;
}
}
//代理工厂
public class JdkProxyFactory {
public static Object getProxy(Object target) {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(), // 目标类的类加载
target.getClass().getInterfaces(), // 代理需要实现的接口,可指定多个
new DebugInvocationHandler(target) // 代理对象对应的自定义 InvocationHandler
);
}
}
/**
* jdk动态代理 测试
*/
@Test
public void test2() {
SendMsgService2 smsService = (SendMsgService2) JdkProxyFactory.getProxy(new SendMsgImpl2());
smsService.send();
}
测试结果
CGLIB 动态代理机制
//引入依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
//功能实现类
@Slf4j
public class SendMsgService3 {
public void send(){
log.info("中国移动发短信!!!");
}
}
//MethodInterceptor 实现类
@Slf4j
public class DebugMethodInterceptor2 implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
log.info("cglib代理 执行前");
Object object = methodProxy.invokeSuper(o, objects);
log.info("cglib代理 执行后");
return object;
}
}
//代理工厂
public class CglibProxyFactory {
public static Object getProxy(Class<?> clazz) {
// 创建动态代理增强类
Enhancer enhancer = new Enhancer();
// 设置类加载器
enhancer.setClassLoader(clazz.getClassLoader());
// 设置被代理类
enhancer.setSuperclass(clazz);
// 设置方法拦截器
enhancer.setCallback(new DebugMethodInterceptor2());
// 创建代理类
return enhancer.create();
}
}
/**
* cglib代理 测试
*/
@Test
public void test3() {
SendMsgService3 sendMsgService3 = (SendMsgService3) CglibProxyFactory.getProxy(SendMsgService3.class);
sendMsgService3.send();
}
测试结果