代理模式

定义:为其他对象提供一种代理以控制对这个对象的访问。
代理模式也叫作委托模式,它频繁出现在我们的程序设计中。一般可分为两类,一类是静态代理,一类是动态代理。本篇文章只讲动态代理。
面向横切面编程(AOP),的核心就是采用动态代理机制。
这里出现了一个名词,什么是面向横切面?笔者Google了一下,大胆地下了一个结论,笔者认为,就是所谓的,对一个类中的既定方法,在运行过程中进行一定的补充。打个比方说,我写了一个方法,这个方法已经打包到jar中了,但是有一天我意识到我的方法不完善,需要在这个方法前面和后面加上一些逻辑,这个尴尬的局面,笔者认为就是横切面。用动态代理,就能解决这个问题。

先来一张类图,大致的描述了动态代理
这里写图片描述
在这里,笔者给出一个动态代理通用的模板。

抽象主题

public interface Subject {

    //业务操作
    public void doSomething(String abc);
}

真实主题

public class RealSubject implements Subject {

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

}

动态代理的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 {
        //前置执行
        (new BeforeAdvice()).exec();
        //执行被代理的方法
        Object invoke = method.invoke(this.target, args);
        //后置执行
        (new AfterAdvice()).exec();
        return invoke;
    }
}

动态代理类

public class DynamicProxy<T> {

    public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h){
        //寻找JoinPoint连接点,AOP框架使用元数据定义
        if(true){
            //执行一个前置通知
            (new BeforeAdvice()).exec();
        }
        //执行目标,并返回结果
        return (T)Proxy.newProxyInstance(loader,interfaces, h);     
    }
}

通知接口及实现

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

    public void exec() {
        System.out.println("我是后续通知,我被执行了!");
    }

}

具体业务的动态代理

public class SubjectDynamicProxy extends DynamicProxy{

    public static <T> T newProxyInstance(Subject subject){
        //获得ClassLoader
        ClassLoader loader = subject.getClass().getClassLoader();
        //获得接口数组
        Class<?>[] classes = subject.getClass().getInterfaces();
        //获得handler
        InvocationHandler handler = new MyInvocationHandler(subject);
        return newProxyInstance(loader, classes, handler);
    }
}

场景类

public class Client {

    public static void main(String[] args) {
        //定义一个主题
        Subject subject = new RealSubject();
        //定义主题的代理
        Subject proxy = SubjectDynamicProxy.newProxyInstance(subject);
        //代理的行为
        proxy.doSomething("Finish");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值