代理模式
思想:抽取实现不同接口的不同实现类中公共实现部分
本质:
1、执行公共部分
2、执行被代理类的方法
3、执行公共部分
注意:代理对象会对被代理对象(实现接口)的所有方法进行代理。
代理类和被代理类是兄弟关系,他们继承或实现同一个父类/接口
AOP种的代理模式:目标对象实现接口—JDK代理,没有实现接口—cglib代理
1、静态代理
ClothFactory clothFactory=new NikeClothFactory();
ClothFactory proxy=new StaticProxy(clothFactory);
这两句Java代码的意思:我要代理哪一个接口的哪一个实现类
public interface ClothFactory {
void produceCloth();
}
public class NikeClothFactory implements ClothFactory{
@Override
public void produceCloth() {
System.out.println("业务信息:Nike正在生产中。。。");
}
}
public class StaticProxy implements ClothFactory{
//如果要代理多个接口,就需要修改代码
private ClothFactory clothFactory;
public StaticProxy(ClothFactory clothFactory) {
this.clothFactory = clothFactory;
}
@Override
public void produceCloth() {
System.out.println("日志信息:一大批订单到来。。。");
clothFactory.produceCloth();
System.out.println("日志信息:生产完毕。。。");
}
}
缺点:
1、代理多个接口,被代理类需要修改代码(添加成员)
2、接口拓展业务时,被代理类还得增加代码(重写方法)
2、基于JDK的动态代理
优点:解决了上边这俩问题
public class DynamicProxy {
public static Object getProxyInstance(Object obj){//形参obj指的是被代理类对象
return java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/*
参数详解:
第一个参数为代理类对象;
*/
System.out.println("日志信息:开始。。。");
Object result = method.invoke(obj, args);//代理类本质是执行被代理类的方法,这里的obj是被代理对象
System.out.println("日志信息:结束。。。");
return result; //被代理类的返回值
}
});
}
}
3、cglib动态代理
静态代理和基于JDK的动态代理都是在和接口打交道;cglib直接跟对象打交道
本质是在内存中动态构建子类(即继承被代理类),因此,被代理类不能为final;
因为代理对象可以执行被代理对象中的所有方法,因此可以在目标对象中的方法加final/static达到一个拦截的效果。
public class SuperMan {
public void fly() {
System.out.println("业务信息:超人正在飞");
}
public void walk() {
System.out.println("asdasdasdas");
}
}
//cglib针对某个对象代理;静态和基于JDK的动态代理针对接口代理
public class CglibProxy implements MethodInterceptor {
//被代理对象
private Object obj;
public CglibProxy(Object obj) {
this.obj = obj;
}
//返回代理对象
public Object getProxyInstance(){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(obj.getClass()); //设置父类
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("开始。。。");
Object result = method.invoke(obj, objects); //obj为被代理对象
System.out.println("结束。。。");
return result;
}
}