一、代理设计模式
1、设计模式:前人总结一套解决特定问题的代码
2、代理设计模式优点:
2.1 保护真实对象
2.2 让真实对象职责更明确
2.3 扩展
3、代理设计模式
3.1 真实对象(老总)
3.2 代理对象(秘书)
3.3 抽象对象(抽象功能),(谈小目标)
二、静态代理设计模式
1、由代理对象代理所有真实对象的功能
1.1 自己编写代理类
1.2 每个代理的功能需要单独编写
2、静态代理设计模式的缺点:
2.1 当代理功能比较多时,代理类中方法需要写很多
三、动态代理
1、为了解决静态代理频繁编写代理功能缺点
2、分类:
2.1、JDK提供的
2.2、cglib 动态代理
四、JDK动态代理
1、和 cglib动态代理对比
1.1、 优点:jdk自带,不需要额外导入jar
1.2、缺点:
1.2.1 真实对象必须实现接口
1.2.2 利用反射机制,效率不高
2、基于反射实现动态代理
实例:
public class Laozong implements Gongneng{ @Override public void chifan() { System.out.println(" 吃饭"); } @Override public void xiaomubiao() { System.out.println(" 谈小目标"); } }
public interface Gongneng { void chifan(); void xiaomubiao(); }
public class Mishu implements InvocationHandler{ private Laozong laozong=new Laozong(); @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("您有预约时候吗???"); Object result = method.invoke(laozong, args); System.out.println("收集访客信息"); return result; } }
public class Women { public static void main(String[] args) { Mishu mishu=new Mishu(); //第一个参数:类加载器 //第二个参数:proxy需要实现什么接口 //第三个参数:通过接口对象调用方法时,需要调用哪个类的invoke方法 Gongneng gongneng = (Gongneng) Proxy.newProxyInstance(Women.class.getClassLoader(),new Class[]{Gongneng.class},mishu); gongneng.chifan(); gongneng.xiaomubiao(); } }
五、cglib动态代理
1、cglib优点:
1.1 基于字节码,生成真实对象的子类
1.1.1 运行效率高于JDK动态代理
1.2 不需要实现接口
2、cglib缺点:
2.1 非JDK功能,需要额外导入jar
3、使用spring aop时,只要出现Proxy 和真实对象转换异常:
3.1、 设置为true 使用 cglib
3.2、设置为false使用 jdk(默认值)
<aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>
4、实例:
public class Laozong { public void chifan(){ System.out.println("吃饭"); } public void xiaomubiao(){ System.out.println("小目标"); } }
public class Mishu implements MethodInterceptor{ @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("预约时间"); Object result = arg3.invokeSuper(arg0, arg2); System.out.println("收集信息"); return result; } }
public class Women { public static void main(String[] args) { Enhancer enhan=new Enhancer(); enhan.setSuperclass(Laozong.class); enhan.setCallback(new Mishu()); Laozong laozong = (Laozong) enhan.create(); laozong.chifan(); laozong.xiaomubiao(); } }