- 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);
- }