一、前言
关于apache的commons-lang开源包中对java.lang无事务支持的功能增强org.apache.commons.lang3.event.EventUtils事务工具类,对对象事务增加监听addEventListener、对监听目标对象方法的绑定bindEventsToMethod等操作。
二、源码说明
其中org.apache.commons.lang3.reflect.MethodUtils参考其它文章
package org.apache.commons.lang3.event;@b@@b@import java.lang.reflect.InvocationHandler;@b@import java.lang.reflect.InvocationTargetException;@b@import java.lang.reflect.Method;@b@import java.lang.reflect.Proxy;@b@import java.util.Arrays;@b@import java.util.HashSet;@b@import java.util.Set;@b@import org.apache.commons.lang3.reflect.MethodUtils;@b@@b@public class EventUtils@b@{@b@ public static <L> void addEventListener(Object eventSource, Class<L> listenerType, L listener)@b@ {@b@ try@b@ {@b@ MethodUtils.invokeMethod(eventSource, "add" + listenerType.getSimpleName(), new Object[] { listener });@b@ } catch (NoSuchMethodException e) {@b@ throw new IllegalArgumentException("Class " + eventSource.getClass().getName() + " does not have a public add" + listenerType.getSimpleName() + " method which takes a parameter of type " + listenerType.getName() + ".");@b@ }@b@ catch (IllegalAccessException e)@b@ {@b@ throw new IllegalArgumentException("Class " + eventSource.getClass().getName() + " does not have an accessible add" + listenerType.getSimpleName() + " method which takes a parameter of type " + listenerType.getName() + ".");@b@ }@b@ catch (InvocationTargetException e)@b@ {@b@ throw new RuntimeException("Unable to add listener.", e.getCause());@b@ }@b@ }@b@@b@ public static <L> void bindEventsToMethod(Object target, String methodName, Object eventSource, Class<L> listenerType, String[] eventTypes)@b@ {@b@ Object listener = listenerType.cast(Proxy.newProxyInstance(target.getClass().getClassLoader(), new Class[] { listenerType }, new EventBindingInvocationHandler(target, methodName, eventTypes)));@b@@b@ addEventListener(eventSource, listenerType, listener);@b@ }@b@@b@ private static class EventBindingInvocationHandler@b@ implements InvocationHandler@b@ {@b@ private final Object target;@b@ private final String methodName;@b@ private final Set<String> eventTypes;@b@@b@ EventBindingInvocationHandler(Object target, String methodName, String[] eventTypes)@b@ {@b@ this.target = target;@b@ this.methodName = methodName;@b@ this.eventTypes = new HashSet(Arrays.asList(eventTypes));@b@ }@b@@b@ public Object invoke(Object proxy, Method method, Object[] parameters)@b@ throws Throwable@b@ {@b@ if ((this.eventTypes.isEmpty()) || (this.eventTypes.contains(method.getName()))) {@b@ if (hasMatchingParametersMethod(method))@b@ return MethodUtils.invokeMethod(this.target, this.methodName, parameters);@b@@b@ return MethodUtils.invokeMethod(this.target, this.methodName, new Object[0]);@b@ }@b@@b@ return null;@b@ }@b@@b@ private boolean hasMatchingParametersMethod(Method method)@b@ {@b@ return (MethodUtils.getAccessibleMethod(this.target.getClass(), this.methodName, method.getParameterTypes()) != null);@b@ }@b@ }@b@}