最近准备用socket和jdk动态代理实现最简单的RPC远程调用,这里先将我写的动态代理贴出来,欢迎批评指正~
目标接口
package testProxy;
public interface TargetInterface {
void targetMehtod(String param);
}
被代理目标实现类
package testProxy;
import org.junit.Test;
public class Target implements TargetInterface{
@Test
public void targetMehtod(String param){
System.out.println("被代理的目标方法。参数为:");
}
}
切入类
package testProxy;
public class MyAspect {
public void before(String strParam,int intParam){
System.out.println("有参before方法执行.参数1为:" + strParam + ",参数2为:" + intParam);
}
public void before(){
System.out.println("无参before法执行");
}
public void after(String param){
System.out.println("有参after方法执行.参数为:" + param);
}
public void after(){
System.out.println("无参after方法执行.");
}
}
动态代理工厂
package testProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 自定义灵活的动态代理
*/
public class MyReflictProxy {
/**
* 得到动态代理对象
* @param target 目标对象
* @param targetMethodName 目标对象方法名
* @param aspect 定义切入方法的类
* @param apectBeforeMethod 执行前插入的方法
* @param beforeParams 执行前方法传入参数
* @param apectAfterMethod 执行后插入的方法
* @param afterParams 执行后方法传入参数
* @return 代理对象
*/
public static Object getProxyObject(final Object target, final String targetMethodName,
final Object aspect, final String apectBeforeMethod,
final Object[] beforeParams, final String apectAfterMethod,
final Object[] afterParams){
return Proxy.newProxyInstance(ProxyFactory.class.getClassLoader(),
target.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Method aspectBefore;
Method aspectAfter;
//无参
if(null == beforeParams){
aspectBefore = aspect.getClass().getDeclaredMethod(apectBeforeMethod);
aspectBefore.invoke(aspect);
}else{
//存放所有参数的class
Class[] allBeforeParamClasses = new Class[beforeParams.length];
int i = 0;
//获取所有参数的class
for (Object param : beforeParams){
//若为Integer类型则转为int.class
if(param instanceof Integer){
allBeforeParamClasses[i] = int.class;
}else if(param instanceof Long){
allBeforeParamClasses[i] = long.class;
}else{
allBeforeParamClasses[i] = param.getClass();
}
i++;
}
aspectBefore = aspect.getClass().getDeclaredMethod(apectBeforeMethod,allBeforeParamClasses);
aspectBefore.invoke(aspect,beforeParams);
}
Object back = method.invoke(target, args);
if(null == afterParams){
aspectAfter = aspect.getClass().getDeclaredMethod(apectAfterMethod);
aspectAfter.invoke(aspect);
}else{
Class[] allAfterParamClasses = new Class[afterParams.length];
int i = 0;
for (Object param : afterParams){
if(param instanceof Integer){
allAfterParamClasses[i] = int.class;
}else if(param instanceof Long){
allAfterParamClasses[i] = long.class;
}else{
allAfterParamClasses[i] = param.getClass();
}
i++;
}
aspectAfter = aspect.getClass().getDeclaredMethod(apectAfterMethod,allAfterParamClasses);
aspectAfter.invoke(aspect,afterParams);
}
return back;
}
});
}
}
测试类
package testProxy;
import org.junit.Test;
/**
* 动态代理测试
*/
public class Run {
@Test
public void testMyProxy() {
TargetInterface testTarget1 = (TargetInterface) MyReflictProxy.getProxyObject(new Target(),
"targetMehtod",new MyAspect(),"before",
new Object[]{"有参beforeMehtod",1},"after",new Object[]{"有参beforeMehtod"});
TargetInterface testTarget2 = (TargetInterface) MyReflictProxy.getProxyObject(new Target(),
"targetMehtod",new MyAspect(),"before",
null,"after",null);
testTarget1.targetMehtod("targetMehtod");
System.out.println();
testTarget2.targetMehtod("targetMehtod");
}
}