1代理设计模式
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 动态代理
1.jdk动态代理
1. 和 cglib 动态代理对比
1.1 优点:jdk 自带,不需要额外导入 jar
1.2 缺点:
1.2.1 真实对象必须实现接口
1.2.2 利用反射机制.效率不高.
2. 使用 JDK 动态代理时可能出现下面异常
2.1 出现原因:希望把接口对象转换为具体真实对象
步骤:
1.定义一个接口
public interface GongNeng {
public void chiFan();
public void talk();
}
2.编写代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyProxy implements InvocationHandler{
private Boss boss=new Boss();
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//proxy表示代理类,method表示代理方法,args表示代理方法的参数
System.out.println(proxy .getClass().getName());
System.out.println(method.getName());
/*for(Object obj:args) {
System.out.println(obj);
};*/
Object result=method.invoke(boss, args);
return result;
}
}
3.编写测试类
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
MyProxy pro=new MyProxy();
GongNeng gong=(GongNeng)Proxy.newProxyInstance(ProxyTest.class.getClassLoader(), new Class[] {GongNeng.class},pro);
/*
* loader: 一个ClassLoader对象,定义了由哪个
* ClassLoader对象来对生成的代理对象进行加载
* interfaces:一个Interface对象的数组,表示的
* 是我将要给我需要代理的对象提供一组什么接口,
* 如果我提供了一组接口给它,那么这个代理对象
* 就宣称实现了该接口(多态),这样我就能调用这
* 组接口中的方法了
* h: 一个InvocationHandler对象,表示的是当我
* 这个动态代理对象在调用方法的时候,会关联到哪一
* 个InvocationHandler对象上
*/
gong.chiFan();
gong.talk();
}
}
2.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(默认值)
实现步骤:
1.
public class CompanyBoss {
public void eat() {
System.out.println("和客户吃饭!");
};
public void talk() {
System.out.println("和客户谈生意!");
};
}
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class BossHelper implements MethodInterceptor{
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
Object result=arg3.invokeSuper(arg0, arg2);
return result;
}
}
import net.sf.cglib.proxy.Enhancer;
public class CglibProxy {
public static void main(String[] args) {
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(CompanyBoss.class);
enhancer.setCallback(new BossHelper());
CompanyBoss boss=(CompanyBoss) enhancer.create();
boss.eat();
boss.talk();
}
}