一. 代理设计模式
(1)设计模式:前人总结的一套解决特定问题的代码。
(2)代理设计模式:
① 真实对象(老总)
② 代理对象(秘书)
③ 抽象对象又叫抽象功能(谈小目标)
(3)代理设计模式优点:
① 保护真实对象
② 让真实对象职责更明确
③ 扩展
二. 静态代理设计模式
1.由代理对象代理所有真实对象的功能
(1)自己编写代理类
(2)每个代理的功能需要单独编写
2.静态代理设计模式缺点
当代理功能比较多时,代理类中方法需要写很多。
【代码示例】
真实对象:
package com.ouc.pojo;
public class LaoZong implements GongNeng{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public LaoZong(String name) {
super();
this.name = name;
}
public LaoZong() {
super();
// TODO Auto-generated constructor stub
}
public void zhidingxiaomubiao(){
System.out.println("制定小目标");
}
}
代理对象:
package com.ouc.pojo;
public class MiShu implements GongNeng{
private LaoZong laoZong = new LaoZong("云云");
@Override
public void zhidingxiaomubiao() {
System.out.println("请问您要找马总吗");
laoZong.zhidingxiaomubiao();
System.out.println("把访客信息备注");
}
}
抽象功能:
package com.ouc.pojo;
public interface GongNeng {
void zhidingxiaomubiao();
}
三. 动态代理设计模式
1.为了解决静态代理频繁编写代理功能的缺点
2.分类:JDK动态代理和cglib动态代理
3.1 JDK动态代理
- 和cglib动态代理相比:
(1)优点:JDK自带,不需要额外导入jar。
(2)缺点:
①真实对象必须实现接口
②利用反射机制,效率不高
【代码示例】
抽象功能
package com.ouc.pojo;
public interface GongNeng {
void chifan();
void mubiao();
}
真实对象:
package com.ouc.pojo;
public class LaoZong implements GongNeng{
@Override
public void chifan() {
System.out.println("吃法");
}
@Override
public void mubiao() {
System.out.println("目标");
}
}
代理对象
package com.ouc.pojo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
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;
}
}
测试
package com.ouc.pojo;
import java.lang.reflect.Proxy;
public class FangKe {
public static void main(String[] args) {
MiShu mishu = new MiShu();
//第一个参数:反射使用的类加载器
//第二个参数:Proxy需要实现什么借口
//第三个参数:通过接口对象调用方法时,需要调用那个类的invoke方法
GongNeng gongNeng = (GongNeng) Proxy.newProxyInstance(FangKe.class.getClassLoader(), new Class[]{GongNeng.class}, mishu);
gongNeng.chifan();
}
}
结果
3.2 cglib动态代理
(1) cglib优点:
① 基于字节码,生成真实对象的子类。
② 运行效率高于JDK动态代理
③ 不需要实现接口
(2)cglib缺点:
非JDK功能,需要额外导入jar
(3)使用Spring aop时,只要出现Proxy和真实对象转换异常
①设置为true,使用cglib
②设置为false,使用jdk
<!--proxy-target-class
true 使用cglib动态代理
false 使用jdk动态代理
-->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
1.导入jar
2. 真实对象:
package com.ouc.pojo;
public class LaoZong{
public void chifan() {
System.out.println("吃法");
}
public void mubiao() {
System.out.println("目标");
}
}
- 代理对象
package com.ouc.pojo;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class MiShu implements MethodInterceptor{
// arg0 子类对象
// arg1 代理的方法
// arg2 参数
// arg3 子类重写方法
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
System.out.println("预约时间");
/*arg1.invoke(arg0, arg2);*/
Object result = arg3.invokeSuper(arg0, arg2);
System.out.println("备注");
return result;
}
}
- 测试类
package com.ouc.pojo;
import net.sf.cglib.proxy.Enhancer;
public class FangKe {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(LaoZong.class);
enhancer.setCallback(new MiShu());
LaoZong laozong = (LaoZong) enhancer.create();
laozong.chifan();
}
}
- 结果