简述
提到代理模式,脑海中第一个想到的就是springAop。日常工作中,我们用springAop来实现统一权限管理,统一日志管理,统一数据库事务处理等等任务。
上面提到的任务就是代理模式的作用。它能在不改变原有功能的基础上增加新的特性。所以说代理模式符合面向对象设计的开闭原则
开闭原则:对扩展开放,对修改关闭
在我们的日常生活中,明星和经纪人的关系很像代理模式的运作模式。活动主办方通过和经纪人联系,然后让经纪人安排明星的演出活动。这里活动主办方是调用者,明星是真实对象,而经纪人就是代理对象。明星只需要负责活动的演出,其他的一切事情都由经纪人去处理。
这个例子也体现了代理模式的另一个作用。就明星而言,经纪人能让其更加专注于演出,而不用去考虑其他与演出关系不大的事情。很多情况下,我们使用代理模式的初衷可能也是如此,抽出公共的不属于业务的部分,让业务开发人员更专注于业务逻辑的处理
分类
下面我们看看代理模式的分类
Snipaste_2019-07-13_20-57-30.png-
从代理类是否需要手动编写来分
- 代码编译运行之前需要手动编写代理类:静态代理
- 不需要编写,运行时自动创建代理对象:动态代理
-
动态代理从真实对象是否需要实现接口
- 实现了接口:jdk和cglib都可以
- 不需要实现接口:只能时cglib
springAOP默认是当真实对象实现了接口采用jdk动态代理,没有实现接口采用cglib动态代理。
代码实现
最后我们看看代码怎么实现
1. 无代理
//真实对象
public class RealObject{
public void doSomething(){
System.out.println("real object do something");
}
}
//调用者
@Test
public void noProxy(){
RealObject realObject = new RealObject();
realObject.doSomething();
}
2. 静态代理
//真实对象(实现了接口)
public class RealObject implements Iface{
public void doSomething(){
System.out.println("real object do something");
}
}
//接口
public interface Iface {
void doSomething();
}
//代理类
public class StaticProxy implements Iface{
private Iface target;
public StaticProxy(Iface target){
this.target=target;
}
@Override
public void doSomething() {
System.out.println("do something before realObject do something");
target.doSomething();
System.out.println("do something after realObject do something");
}
}
//调用者
@Test
public void staticProxy(){
Iface realObject=new RealObject();
Iface proxy = new StaticProxy(realObject);
proxy.doSomething();
}
3. jdk动态代理
//真实对象(实现了接口)
public class RealObject implements Iface{
public void doSomething(){
System.out.println("real object do something");
}
}
//接口
public interface Iface {
void doSomething();
}
//这个不是代理类,而是代理处理逻辑(不然哪里让你写新增的功能!!!)
public class JdkProxyHandler implements InvocationHandler {
private Object target;
public JdkProxyHandler(Object target){
this.target=target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("do something before realObject do something");
Object invoke = method.invoke(target, args);
System.out.println("do something after realObject do something");
return invoke;
}
}
//调用者
@Test
public void jdkProxy(){
Iface realObject=new RealObject();
Iface proxy = (Iface) Proxy.newProxyInstance(Iface.class.getClassLoader(), new Class[]{Iface.class}, new JdkProxyHandler(realObject));
proxy.doSomething();
}
4. cglib动态代理
需要cglib包,spring项目自带cglib包
//真实对象(不用实现接口)
public class RealObject{
public void doSomething(){
System.out.println("real object do something");
}
}
//这个不是代理类,而是代理处理逻辑(不然哪里让你写新增的功能!!!)
public class CglibProxyHandler implements MethodInterceptor {
private Object target;
public Object getInstance(Object target){
this.target=target;
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(this.target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("do something before realObject do something");
Object invoke = methodProxy.invokeSuper(object, args);
System.out.println("do something after realObject do something");
return invoke;
}
}
//调用者
@Test
public void cglibProxy() {
RealObject realObject = new RealObject();
CglibProxyHandler cglibProxyHandler = new CglibProxyHandler();
RealObject proxy = (RealObject)cglibProxyHandler.getInstance(realObject);
proxy.doSomething();
}
网友评论