您的位置:首页 > 编程语言 > ASP

面向横切面编程(Aspect Oriented Programming)。

2017-08-09 23:35 369 查看
什么是动态代理?

动态代理就是在实现阶段不用关心代理谁,而在运行阶段才指定代理哪个对象。具体说明动态代理是根据被代理的接口生成所有的方法,也就是说给定一个接口,动态代理会宣称“我已经实现该接口的所有方法了”。

面向切面变成(AOP),其核心就是采用了动态代理机制。AOP编程没有使用什么新的技术,但是它对我们的设计、编码有非常大的影响,对于日志、事务、权限等都可以在系统设计阶段不用考虑,而在设计后通过AOP的方式切过去。

代理思路:

动态代理实现代理的职责,业务逻辑Subject实现相关的逻辑功能,两者之间没有必然的相互耦合的关系。通知Advice从另一个切面切入,最终在高层模块也就是Client进行耦合,完成逻辑的封装任务。

抽象主题

public interface Subject {

// 业务操作

public void doSomething(String str);

}

其中的doSomething是一种标识方法,可以有多个逻辑处理方法。

真实主题

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 {

// 执行被代理的方法

return method.invoke(this.target , args);

}

}

动态代理类

public class DynamicProxy<T> {

public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandle h) {

// 寻找JoinPoint连接点,AOP框架使用元数据定义

if(true) {

// 执行一个前置通知

(new BeforeAdvice()).exec();

}

// 执行目标,并返回结果

return (T)Proxy.newProxyInstance(loader, interface , h);

}

}

该方法时重新生成了一个对象,为什么要重新生成?你要使用代理,注意c.getInterfaces()这句话,这是非常有意思的一句话,是说查找到该类的所有接口,然后实现接口的所有方法。当然了,方法都是空的,由谁具体负责接管呢?是new MyInvocationHandler(_Obj)这个对象。于是 我们知道一个类的动态代理类时这样的一个类,由InvocationHandler的实现类实现所有的方法,由其invoke方法接管所有方法的实现。

通知接口及实现

public interface IAdvice {

// 通知只有一个方法,执行即可

}

public class BeforeAdvice implements IAdivce {

public void exec() {

System.out.println("我是前置通知,我被执行了!");

}

}

具体业务的动态代理

public class SubjectDynamicProxy extends DynamicProxy {

public static <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(Stirng[] args) {

// 定义一个主题

Subject subject = new RealSubject();

// 定义主题的代理

Subject proxy = SubjectDynamicProxy.newProxyInstance(subject);

// 代理的行为

proxy.doSomething("Finish");

}

}

动态代理的主要意图就是解决我们常说的“审计”问题,也就是横切面编程,在不改变我们已有的代码结构的情况下增强或控制对象的行为。

注意:要实现动态代理的首要条件是:被代理类必须实现一个接口,回想一下前面的分析吧,当然了,现在也有很多技术如CGLIB可以实现不需要接口也可以实现动态代理的方式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐