import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* Aop动态代理工具类
*
* @author tang
*
*/
public class AopUtils {
/*----------------------------begin test AopUtils------------------------------*/
public static interface I1 {
void i1();
}
public static interface I2 {
void i2();
}
public static interface I3 {
void i3();
}
public static interface T1 {
void t1();
}
public static interface TX {
void tx();
}
public static class A implements I1, I2, I3, T1, TX {
public void i1() {
System.out.println(I1.class.getSimpleName());
}
public void i2() {
System.out.println(I2.class.getSimpleName());
}
public void i3() {
System.out.println(I3.class.getSimpleName());
}
public void t1() {
System.out.println(T1.class.getSimpleName());
}
public void tx() {
System.out.println(TX.class.getSimpleName());
}
}
public static void main(String[] args) {
AopAdapter aopAdapter = new AopAdapter() {
@Override
public void before(Object proxy, Method method, Object[] args) {
System.out.println("before...");
}
@Override
public void after(Object proxy, Method method, Object[] args) {
System.out.println("after...");
}
@Override
public void excep(Object proxy, Method method, Object[] args) {
System.out.println("excep...");
}
};
String[] includeRegexs = { "i*"// 字母"i"开头的方法需要执行AOP
, "\\w\\d" // 方法名第一个字符是字母第二个字符是数字需要执行AOP
};
String[] excludeRegexs = { "*2"// 2结尾的方法不需要执行AOP
};
// excludeRegexs的优先级高于includeRegexs
Object proxy = getProxy(new A(), aopAdapter, aopAdapter, aopAdapter, includeRegexs, excludeRegexs, false);
System.out.println("----------");
((I1) proxy).i1();
System.out.println("----------");
((I2) proxy).i2();
System.out.println("----------");
((I3) proxy).i3();
System.out.println("----------");
((T1) proxy).t1();
System.out.println("----------");
((TX) proxy).tx();
System.out.println("----------");
}
/*----------------------------end test AopUtils------------------------------*/
public static interface CallBefore {
void before(Object proxy, Method method, Object[] args);
}
public static interface CallAfter {
void after(Object proxy, Method method, Object[] args);
}
public static interface ExcepCatch {
void excep(Object proxy, Method method, Object[] args);
}
public static abstract class AopAdapter implements CallBefore, CallAfter, ExcepCatch {
@Override
public void excep(Object proxy, Method method, Object[] args) {
}
@Override
public void after(Object proxy, Method method, Object[] args) {
}
@Override
public void before(Object proxy, Method method, Object[] args) {
}
}
private static boolean exist(Method method, String[] methodNames) {
if (methodNames == null || methodNames.length == 0) {
return false;
}
for (int i = 0; i < methodNames.length; i++) {
if (method.getName().equals(methodNames[i])) {
return true;
}
int indexOf = methodNames[i].indexOf('*');
if (indexOf == 0) {
String back = methodNames[i].substring(indexOf + 1);
if (method.getName().endsWith(back)) {
return true;
}
} else if (indexOf == methodNames[i].length() - 1) {
String front = methodNames[i].substring(0, indexOf);
if (method.getName().startsWith(front)) {
return true;
}
} else {
if (method.getName().matches(methodNames[i])) {
return true;
}
}
}
return false;
}
public static Object getProxy(Object object, AopAdapter aopAdapter, String[] includeRegexs) {
return getProxy(object, aopAdapter, aopAdapter, aopAdapter, includeRegexs, null, false);
}
public static Object getProxy(Object object, AopAdapter aopAdapter, String[] includeRegexs, String[] excludeRegexs) {
return getProxy(object, aopAdapter, aopAdapter, aopAdapter, includeRegexs, excludeRegexs, false);
}
public static Object getProxy(Object object, AopAdapter aopAdapter, String[] includeRegexs, String[] excludeRegexs, boolean isIgroreExcep) {
return getProxy(object, aopAdapter, aopAdapter, aopAdapter, includeRegexs, excludeRegexs, isIgroreExcep);
}
/**
* excludeRegexs的优先级高于includeRegexs
*
* @param object
* 被代理对象
* @param before
* 方法调用之前需要的切入的代码
* @param after
* 方法调用之前需要的切入的代码
* @param excep
* 方法捕获异常时需要的切入的代码
* @param includeRegexs
* 哪些方法需要AOP
* @param excludeRegexs
* 哪些方法不需要AOP
* @param isIgroreExcep
* 是否忽略异常
* @return 实现被代理对象所有接口的代理对象,并在实现的接口方法内切入了一定的代码
*/
public static Object getProxy(final Object object, final CallBefore before, final CallAfter after, final ExcepCatch excep, final String[] includeRegexs,
final String[] excludeRegexs, final boolean isIgroreExcep) {
if (object == null) {
throw new RuntimeException("object is null");
}
if (object.getClass().getInterfaces().length < 1) {
throw new RuntimeException("object is not have implement any interface");
}
if (before == null && after == null && excep == null) {
throw new RuntimeException("parameter all is empty");
}
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
boolean isEmptyIncludeRegexs = includeRegexs == null || includeRegexs.length == 0;
boolean isEmptyExcludeRegexs = excludeRegexs == null || excludeRegexs.length == 0;
boolean isExecuteAop = false;
if (!isEmptyIncludeRegexs && !isEmptyExcludeRegexs) {
isExecuteAop = exist(method, includeRegexs) && !exist(method, excludeRegexs);
} else if (isEmptyIncludeRegexs && isEmptyExcludeRegexs) {
isExecuteAop = false;
} else if (isEmptyIncludeRegexs) {
isExecuteAop = !exist(method, excludeRegexs);
} else if (isEmptyExcludeRegexs) {
isExecuteAop = exist(method, includeRegexs);
}
boolean isExecuteBefore = isExecuteAop && before != null;
boolean isExecuteAfter = isExecuteAop && after != null;
boolean isExecuteExcep = isExecuteAop && excep != null;
if (isExecuteBefore) {
before.before(proxy, method, args);// 切入代码
}
Object result = null;
try {
result = method.invoke(object, args);
} catch (Exception e) {
if (isExecuteExcep) {
excep.excep(proxy, method, args);// 切入代码
}
if (isIgroreExcep) {
e.printStackTrace();
} else {
throw e;
}
}
if (isExecuteAfter) {
after.after(proxy, method, args);// 切入代码
}
return result;
}
});
}
}
如上代码执行所打印的结果为:
----------
before...
I1
after...
----------
I2
----------
before...
I3
after...
----------
before...
T1
after...
----------
TX
----------