import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; public class SimpleBean{ private final String name = "SimpleBean"; private int size; public String getName(){ return this.name; } public int getSize(){ return this.size; } public void setSize( int size ) { this.size = size; } public static void main( String[] args ) throws IntrospectionException { BeanInfo info = Introspector.getBeanInfo( SimpleBean.class ); for ( PropertyDescriptor pd : info.getPropertyDescriptors() ) System.out.println( pd.getName() ); } }
Uberspect有个默认的实现UberspectImpl,该实现使用默认的Introspector完成基本的自省功能。Introspector扩展自基类IntrospectorBase,增添异常日志功能。
public Object execute(Object o, InternalContextAdapter context) throws MethodInvocationException { if (referenceType == RUNT) return null; Object result = getVariableValue(context, rootString); if (result == null && !strictRef) { return EventHandlerUtil.invalidGetMethod(rsvc, context, "$" + rootString, null, null, uberInfo); } try { Object previousResult = result; int failedChild = -1; for (int i = 0; i < numChildren; i++) { if (strictRef && result == null) { String name = jjtGetChild(i).getFirstToken().image; throw new VelocityException("Attempted to access '" + name + "' on a null value at " + Log.formatFileString(uberInfo.getTemplateName(), + jjtGetChild(i).getLine(), jjtGetChild(i).getColumn())); } previousResult = result; //遍历执行子节点的execute方法 result = jjtGetChild(i).execute(result,context); if (result == null && !strictRef) // If strict and null then well catch this // next time through the loop { failedChild = i; break; } } /** ...... */ }
public Object execute(Object o, InternalContextAdapter context) throws MethodInvocationException { if (o instanceof NullInstance && ((NullInstance) o).isNotNull()) { return o; } /* * 获取方法信息 */ VelMethod method = null; Object [] params = new Object[paramCount]; try { // 计算参数类型 final Class[] paramClasses = paramCount > 0 ? new Class[paramCount] : ArrayUtils.EMPTY_CLASS_ARRAY; for (int j = 0; j < paramCount; j++) { params[j] = jjtGetChild(j + 1).value(context); if (params[j] != null) { paramClasses[j] = params[j].getClass(); } } //从cache中获取Method信息 MethodCacheKey mck = new MethodCacheKey(methodName, paramClasses); IntrospectionCacheData icd = context.icacheGet( mck ); if ( icd != null && (o != null && icd.contextData == o.getClass()) ) { method = (VelMethod) icd.thingy; } else { //缓存未命中,调用UberIntrospectImpl.getMethod()执行自省 method = rsvc.getUberspect().getMethod(o, methodName, params, new Info(getTemplateName(), getLine(), getColumn())); if ((method != null) && (o != null)) { icd = new IntrospectionCacheData(); icd.contextData = o.getClass(); icd.thingy = method; //更新缓存 context.icachePut( mck, icd ); } } if (typeOptimum && method instanceof VelMethodImpl) { this.recordedData = icd; } /* * .... */ }
public VelMethod getMethod(Object obj, String methodName, Object[] args, Info i) throws Exception { if (obj == null) { return null; } //调用Inspector.getMethod() Method m = introspector.getMethod(obj.getClass(), methodName, args); if (m != null) { //封装VelMethodImpl return new VelMethodImpl(m); } Class cls = obj.getClass(); // if it's an array if (cls.isArray()) { // check for support via our array->list wrapper m = introspector.getMethod(ArrayListWrapper.class, methodName, args); if (m != null) { // and create a method that knows to wrap the value // before invoking the method return new VelMethodImpl(m, true); } } // watch for classes, to allow calling their static methods (VELOCITY-102) else if (cls == Class.class) { m = introspector.getMethod((Class)obj, methodName, args); if (m != null) { return new VelMethodImpl(m); } } return null; }
public Method getMethod(final Class c, final String name, final Object[] params) throws IllegalArgumentException { try { //调用父类IntrospectorBase.getMethod()方法 return super.getMethod(c, name, params); } catch(MethodMap.AmbiguousException ae) { /*异常处理*/ } return null; }
public Method getMethod(final Class c, final String name, final Object[] params) throws IllegalArgumentException,MethodMap.AmbiguousException { if (c == null) { throw new IllegalArgumentException ("class object is null!"); } if (params == null) { throw new IllegalArgumentException("params object is null!"); } IntrospectorCache ic = getIntrospectorCache(); ClassMap classMap = ic.get(c); if (classMap == null) { classMap = ic.put(c); } return classMap.findMethod(name, params); }
public ClassMap put(final Class c) { //构造ClassMap final ClassMap classMap = new ClassMap(c, log); synchronized (classMapCache) { classMapCache.put(c, classMap); classNameCache.add(c.getName()); } return classMap; }
public ClassMap(final Class clazz, final Log log) { this.clazz = clazz; this.log = log; if (debugReflection && log.isDebugEnabled()) { log.debug("================================================================="); log.debug("== Class: " + clazz); } methodCache = createMethodCache(); if (debugReflection && log.isDebugEnabled()) { log.debug("================================================================="); } }
private MethodCache createMethodCache() { MethodCache methodCache = new MethodCache(log); for (Class classToReflect = getCachedClass(); classToReflect != null ; classToReflect = classToReflect.getSuperclass()) { if (Modifier.isPublic(classToReflect.getModifiers())) { populateMethodCacheWith(methodCache, classToReflect); } Class [] interfaces = classToReflect.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { populateMethodCacheWithInterface(methodCache, interfaces[i]); } } // return the already initialized cache return methodCache; }
public VelPropertyGet getPropertyGet(Object obj, String identifier, Info i) throws Exception { if (obj == null) { return null; } Class claz = obj.getClass(); // 构造get"属性名"()形式的Executor AbstractExecutor executor = new PropertyExecutor(log, introspector, claz, identifier); //构造一个Map形式的Executor if (!executor.isAlive()) { executor = new MapGetExecutor(log, claz, identifier); } // 构造get("属性名")形式的Executor if (!executor.isAlive()) { executor = new GetExecutor(log, introspector, claz, identifier); } //构建is"属性名"形式的executor if (!executor.isAlive()) { executor = new BooleanPropertyExecutor(log, introspector, claz, identifier); } return (executor.isAlive()) ? new VelGetterImpl(executor) : null; }