首页 > 代码库 > Apache commons Proxy简介和动态代理、动态拦截器实现
Apache commons Proxy简介和动态代理、动态拦截器实现
Apache Commons Proxy 是Apache 的一个之项目,封装了 Java 对象代理的一些常用方法。又叫做 动态代理。
动态代理的作用非常大,在很多底层框架中都会用得到,比如struts,Spring等都用到了动态代理,它的原理很简单,就是将你要使用的类,重新生成一个子类或本类,这样框架就可以利用这个新生成的类做一些事情,比如在该类的方法前后加一些代码。
设想一下,不用修改任何已经编写好的代码,只要使用动态代理就可以灵活的加入一些东西,将来要是不喜欢了,不用也不会影响原来的代码。
Apache Commons Proxy 的案例在网上找了很久,有用的资料实在不多,刚好JAVA也自带了动态代理,从JAVA的动态代理看起吧。
接口类
package test.ffm83.commons.proxy;
/**
* 定义一个接口,一个方法
* @author 范芳铭
*/
public interface BusinessProcessor {
public voidprocessBusiness();
}
接口实现类
package test.ffm83.commons.proxy;
/**
* 定义一个类,实现接口
* @author 范芳铭
*/
public class BusinessProcessorImpl implements BusinessProcessor {
@Override
public voidprocessBusiness() {
// TODOAuto-generated method stub
System.out.println("执行处理逻辑单元.....");
}
}
动态代理类
package test.ffm83.commons.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 实现InvocationHandler接口,为对象提供代理(代理类)
* @author 范芳铭
*/
public class BusinessProcessorHandler implements InvocationHandler {
private Object target =null;
BusinessProcessorHandler(Objecttarget) {
this.target =target;
}
public Objectinvoke(Object proxy, Method method, Object[] args)
throws Throwable{
System.out
.println("在执行你的逻辑模块之 前,随便做点什么吧。");
Object result =method.invoke(target, args);
System.out
.println("在执行你的逻辑模块之 后,做点想做的事情吧。");
return result;
}
}
动态代理调用类
package test.ffm83.commons.proxy;
import java.lang.reflect.Proxy;
/**
* 测试这个代理类
* @author 范芳铭
*/
public class BusinessProcessorTest {
public static voidmain(String[] args) {
BusinessProcessorImplbpimpl = new BusinessProcessorImpl();
BusinessProcessorHandlerhandler = new BusinessProcessorHandler(bpimpl);
//这是动态代理的核心方法
BusinessProcessorbp = (BusinessProcessor) Proxy.newProxyInstance(
bpimpl.getClass().getClassLoader(),bpimpl.getClass()
.getInterfaces(),handler);
bp.processBusiness();
}
}
运行结果如下:
在执行你的逻辑模块之 前,随便做点什么吧。
执行处理逻辑单元.....
在执行你的逻辑模块之 后,做点想做的事情吧。
是不是有一种似曾相识的感觉,如果在前面加一段安全认证,后面加一段log记录,是不是有点spring之类的味道了?是不是有一种面向切面编程的感觉。
恭喜,确实如此。
学习了JAVA的动态拦截器的方法,那么用apache commons proxy的动态代理,就要简单不少。
用apache commons proxy 做一个简单的动态代理。
package test.ffm83.commons.proxy.util;
/**
* 定义一个接口,一些方法
* @author 范芳铭
*/
public interface Echo
{
public String echoBack( Stringmessage );
public String echoBack( Stringmessage1, String message2 );
public String echoBack(String[] messages );
public int echoBack( int i );
public boolean echoBack(boolean b );
public void echo();
}
package test.ffm83.commons.proxy.util;
/**
* 简单实现接口方法
* @author 范芳铭
*/
public class EchoImpl extends AbstractEcho
{
public boolean echoBack(boolean b )
{
return b;
}
public String echoBack( Stringmessage1, String message2 )
{
return message1 +message2;
}
public String echoBack(String[] messages )
{
final StringBuffer sb =new StringBuffer();
for( int i = 0; i <messages.length; i++ )
{
String message =messages[i];
sb.append( message );
}
return sb.toString();
}
public int echoBack( int i )
{
return i;
}
public void echo()
{
}
}
主体类
package test.ffm83.commons.proxy;
import java.lang.reflect.Method;
import org.apache.commons.proxy.Invoker;
import org.apache.commons.proxy.ProxyFactory;
import test.ffm83.commons.proxy.util.Echo;
/**
* 利用commons proxy做一个简单的动态代理
* @author 范芳铭
*/
public class CommonsProxyInvoker {
private ProxyFactoryfactory;
private static finalClass[] ECHO_ONLY = new Class[] { Echo.class };
public static voidmain(String[] args) throws Exception {
CommonsProxyInvokerproxy = new CommonsProxyInvoker();
proxy.testInvokerProxy();
}
publicCommonsProxyInvoker() {
factory = newProxyFactory();
}
public voidtestInvokerProxy() throws Exception {
finalInvokerTester tester = new InvokerTester();
System.out.println("....在执行你的逻辑模块之 前,随便做点什么吧。");
final Echo echo= (Echo) factory.createInvokerProxy(tester, ECHO_ONLY);
echo.echoBack("hello");
System.out.println("tester.args[0]:"+ tester.args[0]);
echo.echoBack("2不2", "不2");
System.out.println("tester.args[0]和[1]:" + tester.args[0] + ","
+tester.args[1]);
System.out.println("....在执行你的逻辑模块之 前,随便做点什么吧。");
}
private static classInvokerTester implements Invoker {
private Objectmethod;
private Object[]args;
private Objectproxy;
public Objectinvoke(Object proxy, Method method, Object[] args)
throwsThrowable {
this.proxy= proxy;
this.method= method;
this.args= args;
returnnull;
}
}
}
下面是用apache commons proxy实现简单的拦截器
package test.ffm83.commons.proxy;
import java.lang.reflect.Method;
import org.apache.commons.proxy.Interceptor;
import org.apache.commons.proxy.Invocation;
import org.apache.commons.proxy.ProxyFactory;
import test.ffm83.commons.proxy.util.Echo;
import test.ffm83.commons.proxy.util.EchoImpl;
/**
* 利用commons proxy做一个简单的动态代理拦截器
* @author 范芳铭
*/
public class CommonsProxyInterceptor {
private ProxyFactoryfactory;
private static finalClass[] ECHO_ONLY = new Class[] { Echo.class };
public static voidmain(String[] args) throws Exception {
CommonsProxyInterceptorproxy = new CommonsProxyInterceptor();
proxy.testMethodInvocationImplementation();
}
publicCommonsProxyInterceptor() {
factory = newProxyFactory();
}
public voidtestMethodInvocationImplementation() throws Exception
{
final InterceptorTestertester = new InterceptorTester();
final EchoImpl target =new EchoImpl(); //实现类
final Echo proxy = ( Echo) factory.createInterceptorProxy( target, tester, ECHO_ONLY );
proxy.echo();
System.out.println("tester.arguments :" + tester.arguments);
System.out.println("tester.arguments.length:"+ tester.arguments.length);
target.equals(tester.proxy);
proxy.echoBack( "范芳铭" );
System.out.println("tester.arguments :" + tester.arguments);
System.out.println("tester.arguments.length:" +tester.arguments.length);
System.out.println("tester.arguments[0]:" +tester.arguments[0]);
}
private static classInterceptorTester implements Interceptor
{
private Object[]arguments;
private Method method;
private Object proxy;
private ClassinvocationClass;
public Object intercept(Invocation methodInvocation ) throws Throwable
{
arguments =methodInvocation.getArguments();
method = methodInvocation.getMethod();
proxy =methodInvocation.getProxy();
invocationClass =methodInvocation.getClass();
returnmethodInvocation.proceed();
}
}
}
运行结果
tester.arguments :[Ljava.lang.Object;@2e7263
tester.arguments.length:0
tester.arguments :[Ljava.lang.Object;@157f0dc
tester.arguments.length:1
tester.arguments[0]:范芳铭
Apache commons Proxy简介和动态代理、动态拦截器实现