日期:2014-05-16 浏览次数:20617 次
	private void bean(Object object) throws JSONException {
		this.add("{");
		BeanInfo info;
		try {
			Class clazz = object.getClass();
			info = ((object == this.root) && this.ignoreHierarchy) ? Introspector
					.getBeanInfo(clazz, clazz.getSuperclass())
					: Introspector.getBeanInfo(clazz);
			PropertyDescriptor[] props = info.getPropertyDescriptors();
			boolean hasData = false;
			for (int i = 0; i < props.length; ++i) {
				PropertyDescriptor prop = props[i];
				String name = prop.getName();
				Method accessor = prop.getReadMethod();
				Method baseAccessor = null; //这里增加一个临时变量作为真实希望序列化的属性的accessor方法引用
				if (clazz.getName().indexOf("$$EnhancerByCGLIB$$") > -1) {  //如果是CGLIB动态生成的类
					try {
						//下面的逻辑是根据CGLIB动态生成的类名,得到原本的实体类名
						//例如 EntityClassName$$EnhancerByCGLIB$$ac21e这样
						//的类,将返回的是EntityClassName这个类中的相应方法,若
						//获取不到对应方法,则说明要序列化的属性例如hibernateLazyInitializer之类
						//不在原有实体类中,而是仅存在于CGLib生成的子类中,此时baseAccessor
						//保持为null
						baseAccessor = Class.forName(
								clazz.getName().substring(0,
										clazz.getName().indexOf("$$")))
								.getDeclaredMethod(accessor.getName(),
										accessor.getParameterTypes());
					} catch (Exception ex) {
						log.debug(ex.getMessage());
					}
				}
				else	//若不是CGLib生成的类,那么要序列化的属性的accessor方法就是该类中的方法。
					baseAccessor = accessor;
				//这个判断,根据上面的逻辑,使得仅存在于CGLIB生成子类中的属性跳过JSON序列化
				if (baseAccessor != null) {	
					
					//下面的JSON Annotation的获取也修改为从baseAccessor获取,这样避免了
					//由于CGLIB生成子类而导致某些方法上的JSON Annotation丢失导致处理不该
					//序列化的属性
					JSON json = baseAccessor.getAnnotation(JSON.class);
					if (json != null) {
						if (!json.serialize())
							continue;
						else if (json.name().length() > 0)
							name = json.name();
					}
					//ignore "class" and others
					if (this.shouldExcludeProperty(clazz, prop)) {
						continue;
					}
					String expr = null;
					if (this.buildExpr) {
						expr = this.expandExpr(name);
						if (this.shouldExcludeProperty(expr)) {
							continue;
						}
						expr = this.setExprStack(expr);
					}
					if (hasData) {
						this.add(',');
					}
					hasData = true;
					Object value = accessor.invoke(object, new Object[0]);
					this.add(name, value, accessor);
					if (this.buildExpr) {
						this.setExprStack(expr);
					}
				}
			}
		} catch (Exception e) {
			throw new JSONException(e);
		}
		this.add("}");
	}