1. 代理模式(Proxy Pattern):静态代理
2.动态代理(Dynamic Proxy)
为指定的接口在系统运行期间动态的生成代理对象。
java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler
/**
*动态创建实现了interfaces数组中所有指定接口的实现类对象
*ClassLoader:类加载器,把.class文件加载到内存,形成Class对象
*Class[] interfaces:指定要实现的接口们
*InvocationHandler:代理对象的所有方法(个别不执行,getClass())都会调用InvocationHandler的invoke()方法
*/
Object proxyObject = Proxy.newProxyInstance(ClassLoader classLoader, Class[] interfaces, InvocationHandler h);
InvocationHandler
//在调用代理对象所实现接口中的方法时该方法被调用
public Object invoke(Object proxy, Method method, Object[] args);
* Object proxy:当前对象,即代理对象!在调用谁的方法!
* Method method:当前被调用的方法(目标方法)
* Object[] args:实参!
下面使用JDK的动态代理实现前置/后置增强:
public interface Waiter {
void serve();
void shouQian();
}
public class ManWaiter implements Waiter {
@Override
public void serve() {
System.out.println("服务中...");
}
public void shouQian() {
System.out.println("混蛋,给我钱!");
}
}
/**
* 前置增强
*/
public interface BeforeAdvice {
void before();
}
/**
* 后置增强
*/
public interface AfterAdvice {
void after();
}
package com.hong.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Objects;
/**
* 它用来生成代理对象
* 它需要所有的参数
* * 目标对象
* * 增强
*/
/**
* 1. 创建代理工厂
* 2. 给工厂设置三样东西:
* * 目标对象:setTargetObject(xxx);
* * 前置增强:setBeforeAdvice(该接口的实现)
* * 后置增强:setAfterAdvice(该接口的实现)
* 3. 调用createProxy()得到代理对象
* * 执行代理对象方法时:
* > 执行BeforeAdvice的before()
* > 目标对象的目标方法
* > 执行AfterAdvice的after()
*/
public class ProxyFactory{
private Object targetObject;//目标对象
private BeforeAdvice beforeAdvice;//前置增强
private AfterAdvice afterAdvice;//后置增强
/**
* 用来生成代理对象
* @return
*/
public Object createProxy() {
/*
* 1. 给出三大参数
*/
ClassLoader loader = this.getClass().getClassLoader();
Class[] interfaces = targetObject.getClass().getInterfaces();
InvocationHandler h = (proxy,method,args) -> {
/*
* 在调用代理对象的方法时会执行这里的内容
*/
// 执行前置增强
if(Objects.nonNull(beforeAdvice)) {
beforeAdvice.before();
}
Object result = method.invoke(targetObject, args);//执行目标对象的目标方法
// 执行后置增强
if(Objects.nonNull(afterAdvice)) {
afterAdvice.after();
}
// 返回目标对象的返回值
return result;
};
/*
* 2. 得到代理对象
*/
Object proxyObject = Proxy.newProxyInstance(loader, interfaces, h);
return proxyObject;
}
public Object getTargetObject() {
return targetObject;
}
public void setTargetObject(Object targetObject) {
this.targetObject = targetObject;
}
public BeforeAdvice getBeforeAdvice() {
return beforeAdvice;
}
public void setBeforeAdvice(BeforeAdvice beforeAdvice) {
this.beforeAdvice = beforeAdvice;
}
public AfterAdvice getAfterAdvice() {
return afterAdvice;
}
public void setAfterAdvice(AfterAdvice afterAdvice) {
this.afterAdvice = afterAdvice;
}
}
public static void main(String[] args) {
/**
* 目标是让目标对象和增强都可以切换!
*/
//创建工厂
ProxyFactory factory = new ProxyFactory();
//设置目标对象
factory.setTargetObject(new ManWaiter());
factory.setBeforeAdvice(() -> System.out.println("您好不好!"));
factory.setAfterAdvice(() -> System.out.println("再见不见!"));
Waiter waiter = (Waiter)factory.createProxy();
waiter.shouQian();
//打印结果
您好不好!
混蛋,给我钱!
再见不见!
}
3.动态字节码生成
public class Requestable {
public void request(){
System.out.println("method in Requestable without implement any interface");
}
}
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* Created by John on 2018/10/31.
*/
public class RequestCtrlClallback implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
if (method.getName().equals("request")){
System.out.println("CGLIB proxy");
return methodProxy.invokeSuper(o,objects);
}
return null;
}
}
import net.sf.cglib.proxy.Enhancer;
public class Demo3 {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Requestable.class);
enhancer.setCallback(new RequestCtrlClallback());
Requestable proxy = (Requestable) enhancer.create();
proxy.request();
}
}