前面作了一个Waiter的动态代理的练习,这篇继续来写一个练习,一个动态代理工厂的例子,这个例子在之后学习Spring的时候会有帮助。这个动态工厂的主要做用就是包装了下目标对象和前置加强和后置加强。
java
工厂类的使用步骤程序员
咱们要设计一个动态代理工厂类,如下是使用这个工程类的步骤。ide
来源:凯哥Java(kaigejava)单元测试
1. 建立代理工厂学习
2. 给工厂设置三样东西测试
1) 目标对象,调用方法setTargetObject()this
2) 前置加强,调用setBeforeAdvice(该接口的具体实现)spa
3) 后置加强,调用setAfterAdvice(该接口的具体实现)设计
3. 调用createProxy方法获得代理对象代理
执行代理对象方法时,按照如下顺序执行。
1) 执行BeforeAdvice的before方法
2) 执行目标对象的目标方法
3) 执行AfterAdvice的after方法
前提准备
新建一个包,把前面的Waiter.java 和ManWaiter.java拷贝过来。
建立动态代理工厂类
这里咱们的代理工厂类,先给出目标对象,前置加强和后置加强,而后建立set和get方法。
下面是前置加强接口代码
package demo1;
/**
* 前置加强
* @author anthony
*
*/
public interface BeforeAdvice {
public void before();
}
下面是后置加强接口代码
package demo1;
/**
* 后置加强
* @author anthony
*
*/
public interface AfterAdvice {
public void after();
}
这里面,咱们暂时不知道程序员会在前置加强和后置加强写什么具体代码,因此这里咱们利用接口来实现,程序员到时候写代码的时候,前置加强必需要实现前置加强接口中的before方法,后置加强必须实现后置加强接口中的after方法。
下面是代理工厂类的代码
package demo1;
/**
* 这个类用来生成代理对象
* 须要全部参数
* *目标对象
* *加强
* @author anthony
*
*/
public class ProxyFactory {
private Object targetObject; // 目标对象
private BeforeAdvice beforeAdvice; // 前置加强
private AfterAdvice afterAdvice; // 后置加强
public Object getTargetObject() {
return targetObject;
}
public void setTargetObject(Object targetObject) {
this.targetObject = targetObject;
}
public BeforeAdvice getBeforeAdvice() {
return beforeAdvice;
}
public void setBeforeAdvice(BeforeAdvice beforeAdvice) {
this.beforeAdvice = beforeAdvice;
}
public AfterAdvice getAfterAdvice() {
return afterAdvice;
}
public void setAfterAdvice(AfterAdvice afterAdvice) {
this.afterAdvice = afterAdvice;
}
}
这里三个对象都给生成set和get方法,方便调用。
建立代理对象
前面代码都不是重点,咱们代理工厂重点部分来了,就是如何建立代理对象。这部分是在工厂类中,实现createProxy()方法,是本篇的重点内容,代码以下。
package demo1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.omg.CORBA.portable.InvokeHandler;
/**
* 这个类用来生成代理对象
* 须要全部参数
* *目标对象
* *加强
* @author anthony
*
*/
public class ProxyFactory {
private Object targetObject; // 目标对象
private BeforeAdvice beforeAdvice; // 前置加强
private AfterAdvice afterAdvice; // 后置加强
/**
* 生成代理对象
* @return
*/
public Object createProxy() {
// 1. 给出三大参数
ClassLoader loader = this.getClass().getClassLoader();
Class[] interfaces = targetObject.getClass().getInterfaces();
InvocationHandler h = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 执行前置加强
if(beforeAdvice != null) {
beforeAdvice.before();
}
// 执行目标对象目标方法
Object result = method.invoke(targetObject, args);
// 执行后置加强
if(afterAdvice != null) {
afterAdvice.after();
}
return result;
}
};
// 2. 获得代理对象
Object proxyObject = Proxy.newProxyInstance(loader, interfaces, h);
return proxyObject;
}
public Object getTargetObject() {
return targetObject;
}
public void setTargetObject(Object targetObject) {
this.targetObject = targetObject;
}
public BeforeAdvice getBeforeAdvice() {
return beforeAdvice;
}
public void setBeforeAdvice(BeforeAdvice beforeAdvice) {
this.beforeAdvice = beforeAdvice;
}
public AfterAdvice getAfterAdvice() {
return afterAdvice;
}
public void setAfterAdvice(AfterAdvice afterAdvice) {
this.afterAdvice = afterAdvice;
}
}
上面代码就是在createProxy()方法的时候,把目标对象和加强给作了如下组装。接下来,看看如何代码使用这个工厂类。
测试工厂类的使用
新建一个Demo1.java文件,写代码来使用ProxyFactory这个动态代理工厂类。
package demo1;
import org.junit.Test;
public class Demo1 {
@Test
public void fun1() {
// 1. 建立工厂类对象
ProxyFactory factory = new ProxyFactory();
// 2.设置目标对象
factory.setTargetObject(new ManWaiter());
// 3.设置前置加强
factory.setBeforeAdvice(new BeforeAdvice() {
public void before() {
System.out.println("你好,欢迎光临!");
}
});
// 4.设置后置加强
factory.setAfterAdvice(new AfterAdvice() {
public void after() {
System.out.println("再见,欢迎下次再来!");
}
});
// 5. 获取代理对象, 执行加强代码
Waiter waiter = (Waiter)factory.createProxy();
waiter.serve();
}
}
运行单元测试,获得以下输出。
联系凯哥:凯哥Java(kaigejava)
凯哥我的博客:www.kaigejava.com
我的博客上能够发即时消息给凯哥哦~
你好,欢迎光临!
服务中...
再见,欢迎下次再来!