Proxy
|
代理类
|
Target
|
通过
Proxy
返回一个代理类
|
当调用代理类的时候它会调用目标对象的方法()
|
public static Object newProxyInstance(ClassLoader loader,
Class>[] interfaces,
InvocationHandler h)
的第1个参数传入一个类加载器,一般都是用加载本类的类加再器,第2个参数就是这个代理类要实现的接口,也就是要用这些接口创建出一个复制对象,第3个参数是一个实现了InvocationHandler 接口的类,当代理类调用方法的时候他就会调用实现了InvocationHandler类的 invoke
(Object proxy, Method method, Object[] args)
在这里我们就可以加入一些代码了,因该代理类在执行每个方法的时候都会来执行这个方法。
public class MyInvocationHandler implements InvocationHandler
{
Student stu = new Student();
//传入目标对象
public MyInvocationHandler(Student stu)
{
this.stu = stu;
}
public synchronized Object invoke(Object proxy, Method method, Object[] args) throws Exception
{
System.out.println("Proxy haha!");
System.out.println(proxy.getClass().getName());
//调用目标对象对应的方法
return method.invoke(stu,args);
}
}
这样我们就实现了一个代理类,代理类外表和目标类一样,因为他们都实现了同一的接口,上面代码代理类的方法别调用的时候实际会去打印System.out.println("Proxy haha!");
然后调用目标对象对应的方法。
注意:上面指的目标对象也是实现了接口的, JDK的代理类只能通过接口代理,如果你的类没实现任何接口,那么必须通过一个CGLIB的框架。它的实现代理是创建目标对象的子类。如果要了解CGLIB请网上查看。
通过上面的讲解我们知道了代理类的实现内幕。现在让我们来看看Spring里的ProxyFactoryBean。要了解ProxyFactoryBean首先了了解几个概念。
切面:
切面是你要实现的交叉功能。他是应用系统模块化的一个切面或领域。切面的最常见列子就是日志记录,日志记录在系统中到处需要要用到,利用继承来重用日志模块不合适。然而,你可以创建一个日志记录的切面,并且使用APP在系统中应用。
连接点:
连接点是应用系统执行过程中插入切面的地方。这个地方可以是方法调用,异常抛出,或者甚至是要修改的字段。切面代码在这些地方插入到你的应用流程中,添加新的行为。
通知:
通知切面的实际实现。它通知应用系统新的行为。在日志列子中,日志通知包含实现实际日志功能代码,如向日志文件写日志。通知在连接点插入到应用系统中。
切入点
切入点定义了通知因该在那些连接点。通知可以应用到AOP框架支持的任何连接点。当然,你并不希望把所有切面应用到所有可能的连接点上。切入点让你指定通知应用到那些地方。通常通过指定类名和方法名,或者匹配类名和方法名式样的正则表达式来指定切入点。