代理模式:
大话设计模式中对代理模式的描述是为其他对象提供一种代理以控制对这个对象的访问。
举个栗子,例如我们有个是实体方法实体方法eat()就是吃饭,但是过了一段时间后我想在吃饭前进行祈祷,我们不得不去修改这个eat()方法,改一次两次还好,单如果之后在吃饭前又有其他的事情,我们就需要不停的去修改它,代码也会贼臃肿,代理模式也就应运而生,我们不修改原来的方法,只是在之前原有的功能上添加业务处理,完美符合了俺们的开闭原则。
实现JDK动态代理:
首先设置我们的公共接口(代理模式需要实现公共接口):
//公共接口
package proxy;
public interface person {
void saySb();
void hh();
}
声明具体的实现类:
package proxy;
//实现person的具体实现类
public class Student implements person{
@Override
public void saySb() {
// TODO Auto-generated method stub
System.out.println("i am a student");
}
@Override
public void hh() {
// TODO Auto-generated method stub
System.out.println("测试二");
}
}
封装调用:
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.junit.Test;
public class JDKProxyTest {
//用来生成我们代理类的方法
public static person creatProxy(){
//这是我们的目标类,也就是被代理对象,因为之后的调用是匿名内部类,所以需要声明成final类型
final person pe1 = new Student();
/*以下是我们生成代理类的具体过程:
*
*
* @param class loader:方法的第一个参数,类加载器,一半传入当前类。
*
* @param proxy interfaces:代理类
* 需要实现的所有接口,因为代理类跟
* 例.getClass().getInterfaces()注
* 意:只能获得自己接口,不能获得父元素
* 接口
*
* 第三个参数是 处理类,接口
* @invokeHandle class
*
* @param 1.proxy class
*
* @param 2.proxy method (by reflect get)
* @param 1.proxy args
*
* 在最终生成的代理类中,执行方法,其实就是执行处理类(InvocationHandler)中的invoke方法,也就是调用自己本身,在调用本身的同时通过反射将目标类传入,在目标方法前后,做前置,或者后置处理。
*/
person pe = (person) Proxy.newProxyInstance(
JDKProxyTest.class.getClassLoader(),
pe1.getClass().getInterfaces(),
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//执行前
System.out.println("前");
//执行目标方法
Object invoke = method.invoke(pe1, args);
//执行后
System.out.println("后");
return invoke;
}
});
return pe;
}
测试:
public static void main(String[] args) {
person pe = creatProxy();
pe.saySb();
}
结果:
前
i am a student
后