在Spring中,有很多设计模式被应用,其中不乏代理模式。而代码模式中,就一定少不了动态代理模式。今天就对动态代理模式进行学习记录。
代理模式
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
动态代理:
代理类在程序运行时创建的代理方式被成为动态代理;动态代理有两种实现方式,一个是在java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过这个类和这个接口可以生成JDK动态代理类和动态代理对象。另一种是,spring使用CGLIB库生成目标对象的子类。
我们先制造个代理场景,分别用两种方式进行实现。
我们每人人都要买房,买房的过程中,需要中介帮我们做一些事情。这个过程,就属于代理了。中介,就是其中的代理类。
1.jdk动态代理:
1.1先定义一个人类:
public interface IPerson {
void buyHouse();
}
李先生想买房
public class LiSir implements IPerson {
@Override
public void buyHouse() {
System.out.println("想买120平米的房子");
}
}
3.jdk动态代理处理
public class JdkProxy implements InvocationHandler {
private IPerson target;
public JdkProxy(IPerson target) {
this.target = target;
}
public IPerson getInstance(){
return (IPerson) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始找目标群体");
Object object = method.invoke(target,args);
System.out.println("找到,交易");
return object;
}
}
4.写个测试demo
public static void main(String[] args) {
JdkProxy jdkProxy = new JdkProxy(new LiSir());
jdkProxy.getInstance().buyHouse();
}
2.1接下来用CGLIB的动态代理实现
public class WuSir {
public void buyHouse() {
System.out.println("想买90平米");
}
}
cglib的动态代理处理:
public class CglibProxy implements MethodInterceptor {
public Object getInstance(Class<?> clazz){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
// 这里处理
System.out.println("开始找目标群体");
Object object = methodProxy.invokeSuper(o,objects);
System.out.println("找到,交易");
return object;
}
}
最后写个测试类看下结果
public static void main(String[] args) {
WuSir wuSir = (WuSir) new CglibProxy().getInstance(WuSir.class);
wuSir.buyHouse();
}
动态代理记录到这里。