1、代理模式的定义
为某个对象提供一种代理,以控制对这个对象的访问
2、代理模式的实现要点
静态代理:在编译期就确定好代理类,通过代理类来执行被代理类的方法
动态代理:在运行期才确定好代理类,通过代理类来执行被代理类的方法(框架使用)
3、应用场景
无侵入对散落各处的方法调用进行增强(AOP),比如日志记录,性能统计,安全控制,事务处理,异常处理
4、实现举例
静态代理
public class StaticProxy implements GamPlayer {
private GamPlayer gamPlayer;
public StaticProxy(GamPlayer gamPlayer){
this.gamPlayer = gamPlayer;
}
public void killBoss(){
gamPlayer.killBoss();
}
public void upgrade(){
gamPlayer.upgrade();
}
public static GamPlayer getStaticProxy(GamPlayer player){
return new StaticProxy(player);
}
public static void main(String[] args) {
GamPlayer player = new GamPlayerImpl();
GamPlayer staticProxy = StaticProxy.getStaticProxy(player);
staticProxy.killBoss();
staticProxy.upgrade();
}
}
动态代理
public class DynamicProxy implements InvocationHandler {
private Object target;//被代理的对象
public DynamicProxy(Object target){
this.target = target;
}
//动态代理类调用upgrade方法,先调用InvocationHandler中的invoke,再通过invoke调用被代理类gamplayer的方法
//proxy 代理类的实例,可以用来获取代理对象的信息和可以将代理对象返回进行连续调用,其他时候都无作用
//method被代理类的方法,args被代理类方法的参数,返回值:表示当前执行方法的返回值
public Object invoke(Object proxy,Method method,Object[] args) throws Exception{
System.out.println("proxy = " + proxy.getClass().getName() );
System.out.println("我是前置通知"); //每个方法执行前的前置通知
Object result = method.invoke(target,args);
System.out.println("我是后置通知"); //每个方法执行后的后置通知
return result;
}
public static Object getDynamicProxy(Object target){
InvocationHandler invocationHandler = new DynamicProxy(target);
//通过类加载器、类方法,可以反射出类的实例,调用处理方法invocationHandler,主要定义动态代理调用被代理类的方法
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),invocationHandler);
}
public static void main(String[] args) {
GamPlayer gamPlayer = new GamPlayerImpl();
GamPlayer dynamicGamPlayer =(GamPlayer) DynamicProxy.getDynamicProxy(gamPlayer);
dynamicGamPlayer.upgrade();
dynamicGamPlayer.killBoss();
}
}
cglib 实现动态代理(非实现接口的类的代理)
public class CglibDynamicProxy implements MethodInterceptor {
public Object target;//被代理对象
public CglibDynamicProxy(Object target){
this.target = target;
}
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("这里可以插入执行关键代码之前的逻辑");
System.out.println(String.format("object is %",object.getClass().getName()));
Object result = methodProxy.invokeSuper(object,args);
System.out.println("这里可以插入执行关键代码之后的逻辑");
return result;
}
public static Object getCglibDynamicProxy(Object target){
CglibDynamicProxy methodInterceptor = new CglibDynamicProxy(target);
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(methodInterceptor);
return enhancer.create();
}
public static void main(String[] args) {
GamPlayerImpl gamPlayer = new GamPlayerImpl();
GamPlayerImpl cglibDynProxy = (GamPlayerImpl) CglibDynamicProxy.getCglibDynamicProxy(gamPlayer);
cglibDynProxy.killBoss();
cglibDynProxy.upgrade();
}
}