设计模式 _第六招式_代理模式(动态代理)

一、定义

动态代理是在实现阶段不用关心代理的是谁,而在运行阶段才指定代理哪个对象。面向切面编程(AOP)其核心就是采用的动态代理机制。

二、代码演示

2.1 类图
在这里插入图片描述
上面类图,是两条独立的发展线路。动态代理实现代理的职责,业务逻辑Subject实现先关业务逻辑,两者没有必然的相互耦合的关系。通知Advices从另外一个切面切入,最终高层通过Client进行耦合,完成业务的逻辑封装。
2.2 业务逻辑抽象主题

public interface Subject {
    //业务操作
    public void  doSomething(String str);
}

2.3 业务逻辑真实主题

public class RealSubject implements Subject {

    public void  doSomething(String str){
        System.out.println("do something!---------->"+str);
    }
}

2.4 动态代理Handler类

public class MyInvocationHandler implements InvocationHandler {
    //被代理状态
    private  Object target = null ;
    public MyInvocationHandler(Object _obj){
        this.target = _obj;
    }
    //代理方法
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
    //执行被代理的方法
      return  method.invoke(this.target,args);
    }
}

备注:所有通过动态代理实现的方法全部通过invoke方法调用。
2.5 动态代理类

public class DymamicProxy<T> {
    public static <T> T  newProxyInstance(ClassLoader loader, Class<?> []interfaces, InvocationHandler h){
        //寻找JoinPiont连接点,AOP框架使用元数据定义
       if (true){
           (new BeforeAdvice()).exec();
       }
       return (T)Proxy.newProxyInstance(loader,interfaces,h);
    }
}

2.6 通知接口及实现类

public interface IAdvice {
    //通知只有一个方法
    public void exec();
}
public class BeforeAdvice implements IAdvice {
    public void exec(){
        System.out.println("我是前置通知,我被执行了!");
    }
}

2.7 动态代理场景类

public class Client {
    public  static void main(String args[]){
        //定义个主题
        Subject   subject = new RealSubject();
        //定义一个Handler
        InvocationHandler  handler = new MyInvocationHandler(subject);
        //定义一个主题的代理
        Subject subjectProxy = DymamicProxy.newProxyInstance(subject.getClass().getClassLoader(),subject.getClass().getInterfaces(),handler);
        //代理的行为
        subjectProxy.doSomething("Finish");
    }
}

运行结果:

我是前置通知,我被执行了!
do something!---------->Finish

三、优点

3.1 动态代理能有效的从切面实现业务逻辑, 降低与业务代码的耦合度。

四、缺点

五、应用场景

动态代理是一个通用的代理框架,Spirng AOP 和 AspectJ 都是用动态代理实现, 在企业应用动态代理实现权限, 日志,事务处理等业务逻辑。

六、注意事项

6.1 (T)Object object = (T)Proxy.newProxyInstance(c.getClassLoader(), c.getInterfaces(), new MyInvocationHandler(_obj) )
该方法是动态代理的核心由jdk维护,为什么哟啊重新生成对象呢 ? 注意 c.getInterfaces()会查找该类的所有接口,然后new MyInvocationHandler(_obj) 实现接口的所有方法,方法都是空,由其invoke方法接管所有方法的实现,其动态调用过程如图:
在这里插入图片描述
6.2 动态代理必选满足如下逻辑

  1. A、业务代理类必须要实现一个接口,因为“subject.getClass().getInterfaces()”需要取接口信息
  2. B、必须要有一个代理处理类。如:MyInvocationHandler 该类必须实现InvocationHandler接口invoke方法
  3. C、必须生成代理对象。如:Subject subjectProxy = DymamicProxy.newProxyInstance(subject.getClass().getClassLoader(),subject.getClass().getInterfaces(),handler); C、必须生成代理对象。如:Subject subjectProxy = DymamicProxy.newProxyInstance(subject.getClass().getClassLoader(),subject.getClass().getInterfaces(),handler);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值