All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.t.util.common.ReflectUtil Maven / Gradle / Ivy

package cn.t.util.common;

import cn.t.util.common.proxy.ProxyCallback;
import cn.t.util.common.proxy.ProxyConfig;
import net.sf.cglib.proxy.*;

import java.lang.reflect.*;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * JDK与Cglib区别
 * 1.Jdk需要声明接口 Cglib不需要生成接口
 * 2.Jdk代理实力只能用接口类型赋值, Cglib没有此限制
 * 3.在Jdk代理类中调用另外一个方法时不会再进切面, 而在Cglib类中调用另外一个方法依然会进切面
 * 

* 总结: Cglib更方便使用 */ public class ReflectUtil { private static final Map, Method[]> declaredMethodsCache = new ConcurrentHashMap<>(256); private static final Method[] NO_METHODS = {}; public static Object generateCglibProxy(Object target, ProxyConfig config) { CglibProxy proxy = new CglibProxy(target, config.getProxyCallback()); CglibProxyCallbackFilter filter = new CglibProxyCallbackFilter(proxy, config); Enhancer enhancer = new Enhancer(); //设置要被代理的类 enhancer.setSuperclass(target.getClass()); //设置多个拦截器(setCallbacks中的拦截器顺序一定要和callbackFilter中的顺序一致) enhancer.setCallbacks(new Callback[]{proxy, NoOp.INSTANCE}); enhancer.setCallbackFilter(filter); return enhancer.create(); } public static Object generateJdkProxy(Object target, ProxyConfig config) { JdkProxy jdkProxy = new JdkProxy(target, config); return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), jdkProxy); } /** * 获取泛型类型 * @param object xxx * @param parameterizedSuperclass xxx * @param typeParamName xxx * @return xxx */ public static Class findTypeParam(final Object object, Class parameterizedSuperclass, String typeParamName) { final Class thisClass = object.getClass(); Class currentClass = thisClass; for (; ; ) { if (currentClass.getSuperclass() == parameterizedSuperclass) { int typeParamIndex = -1; TypeVariable[] typeParams = currentClass.getSuperclass().getTypeParameters(); for (int i = 0; i < typeParams.length; i++) { if (typeParamName.equals(typeParams[i].getName())) { typeParamIndex = i; break; } } if (typeParamIndex < 0) { throw new IllegalStateException( "unknown type parameter '" + typeParamName + "': " + parameterizedSuperclass); } Type genericSuperType = currentClass.getGenericSuperclass(); if (!(genericSuperType instanceof ParameterizedType)) { return Object.class; } Type[] actualTypeParams = ((ParameterizedType) genericSuperType).getActualTypeArguments(); Type actualTypeParam = actualTypeParams[typeParamIndex]; if (actualTypeParam instanceof ParameterizedType) { actualTypeParam = ((ParameterizedType) actualTypeParam).getRawType(); } if (actualTypeParam instanceof Class) { return (Class) actualTypeParam; } if (actualTypeParam instanceof GenericArrayType) { Type componentType = ((GenericArrayType) actualTypeParam).getGenericComponentType(); if (componentType instanceof ParameterizedType) { componentType = ((ParameterizedType) componentType).getRawType(); } if (componentType instanceof Class) { return Array.newInstance((Class) componentType, 0).getClass(); } } if (actualTypeParam instanceof TypeVariable) { // Resolved type parameter points to another type parameter. TypeVariable v = (TypeVariable) actualTypeParam; currentClass = thisClass; if (!(v.getGenericDeclaration() instanceof Class)) { return Object.class; } parameterizedSuperclass = (Class) v.getGenericDeclaration(); typeParamName = v.getName(); if (parameterizedSuperclass.isAssignableFrom(thisClass)) { continue; } else { return Object.class; } } throw new IllegalStateException("cannot determine the type of the type parameter '" + thisClass + "': " + typeParamName); } currentClass = currentClass.getSuperclass(); if (currentClass == null) { throw new IllegalStateException("cannot determine the type of the type parameter '" + thisClass + "': " + typeParamName); } } } public static Method findMethod(Class clazz, String name, Class... paramTypes) { Assert.notNull(clazz, "Class must not be null"); Assert.notNull(name, "Method name must not be null"); Class searchType = clazz; while (searchType != null) { Method[] methods = (searchType.isInterface() ? searchType.getMethods() : getDeclaredMethods(searchType)); for (Method method : methods) { if (name.equals(method.getName()) && (paramTypes == null || Arrays.equals(paramTypes, method.getParameterTypes()))) { return method; } } searchType = searchType.getSuperclass(); } return null; } private static Method[] getDeclaredMethods(Class clazz) { Assert.notNull(clazz, "Class must not be null"); Method[] result = declaredMethodsCache.get(clazz); if (result == null) { Method[] declaredMethods = clazz.getDeclaredMethods(); List defaultMethods = findConcreteMethodsOnInterfaces(clazz); if (defaultMethods != null) { result = new Method[declaredMethods.length + defaultMethods.size()]; System.arraycopy(declaredMethods, 0, result, 0, declaredMethods.length); int index = declaredMethods.length; for (Method defaultMethod : defaultMethods) { result[index] = defaultMethod; index++; } } else { result = declaredMethods; } declaredMethodsCache.put(clazz, (result.length == 0 ? NO_METHODS : result)); } return result; } private static List findConcreteMethodsOnInterfaces(Class clazz) { List result = null; for (Class ifc : clazz.getInterfaces()) { for (Method ifcMethod : ifc.getMethods()) { if (!Modifier.isAbstract(ifcMethod.getModifiers())) { if (result == null) { result = new LinkedList<>(); } result.add(ifcMethod); } } } return result; } public static boolean isPublicStaticFinal(Field field) { int modifiers = field.getModifiers(); return (Modifier.isPublic(modifiers) && isPublic(modifiers) && isFinal(modifiers)); } public static boolean isPublic(Field field) { int modifiers = field.getModifiers(); return Modifier.isPublic(modifiers); } public static boolean isPublic(int modifiers) { return Modifier.isPublic(modifiers); } public static boolean isFinal(Field field) { int modifiers = field.getModifiers(); return Modifier.isFinal(modifiers); } public static boolean isFinal(int modifiers) { return Modifier.isFinal(modifiers); } /** * 代理 */ private interface BaseProxy { default boolean apply(Method method, String... methods) { if (methods == null || methods.length == 0) { return false; } else { String methodName = method.getName(); for (String m : methods) { if (methodName.equals(m)) { return true; } } return false; } } } private static class CglibProxyCallbackFilter implements CallbackFilter { private BaseProxy proxy; private ProxyConfig config; private CglibProxyCallbackFilter(BaseProxy proxy, ProxyConfig config) { this.proxy = proxy; this.config = config; } @Override public int accept(Method method) { return proxy.apply(method, config.getInterceptMethods()) ? 0 : 1; } } /** * cglib代理 */ private static class CglibProxy implements MethodInterceptor, BaseProxy { private Object target; private ProxyCallback callback; public CglibProxy(Object target, ProxyCallback callback) { this.target = target; this.callback = callback; } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { callback.before(obj, method, args); Object result = methodProxy.invokeSuper(obj, args); callback.after(result); return result; } } /** * jdk代理 */ private static class JdkProxy implements java.lang.reflect.InvocationHandler, BaseProxy { private Object target; private ProxyConfig config; private JdkProxy(Object target, ProxyConfig config) { this.target = target; this.config = config; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { boolean apply = apply(method, config.getInterceptMethods()); if (apply) { config.getProxyCallback().before(target, method, args); } Object result = method.invoke(target, args); if (apply) { config.getProxyCallback().after(result); } return result; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy