代理
代理的意思很好理解,它借鉴了我们日常所用的代理的意思:就是本来该自己亲自去做的某件事,由于某种原因不能直接做,而只能请人代替你做,这个被你请来做事的人就是代理.
代理模式
代理模式中的每一个代理类在编译之后都会生成一个class文件,代理类所实现的接口和所代理的方法都被固定,这种代理被称之为静态代理(Static Proxy)。最大特点是代理类和被代理的类必须实现同样的接口,这就失去了灵活性。代理类和真实主题类都应该是事先已经存在的,代理类的接口和所代理方法都已明确指定,如果需要为不同的真实主题类提供代理类或者代理一个真实主题类中的不同方法,都需要增加新的代理类,这将导致系统中的类个数急剧增加,因此需要想办法减少系统中类的个数。动态代理可以让系统能够根据实际需要来动态创建代理类,让同一个代理类能够代理多个不同的真实主题类而且可以代理不同的方法。这就是动态代理了。
动态代理
Java语言提供了对动态代理的支持:Proxy类
public static Object newProxyInstance(ClassLoader loader, Class<?>[]interfaces, InvocationHandler h)
该方法用于返回一个动态创建的代理类的实例。第一个参数loader表示代理类的类加载器,第二个参数interfaces表示代理类所实现的接口列表,第三个参数h表示所指派的调用处理程序类。
InvocationHandler接口
InvocationHandler接口是代理处理程序类的实现接口,该接口作为代理实例的调用处理者的公共父类,每一个代理类的实例都可以提供一个相关的具体调用处理者(InvocationHandler接口的子类)。该接口很简单,只声明了一个方法:
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
对动态代理对象的调用请求都将会被自动转发给InvocationHandler对象的invoke()方法,由invoke()方法来实现对请求的统一处理。invoke()方法包含三个参数,其中第一个参数proxy表示代理类的实例,第二个参数method表示需要代理的方法,第三个参数args表示代理方法的参数数组。
示例
下面通过利用注解的方式记录log的例子来说明。代码结构如下:
解释下,这里加Delegate层主要有三方面原因,一是对Server进行分发,二是对Delegate层进行代理,三是方便在Delegate层进行日志、异常处理等处理。
Service
首先,完成业务处理,这里主要构造一些数据。
package com.my.web.service.impl;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
import com.my.web.bean.Emp