/** * 获取一个类的某个一个泛型参数 * * @param klass 类 * @param index 参数下标 (从 0 开始) * @return 泛型参数类型 */ @SuppressWarnings("unchecked") public static <T> Class<T> getTypeParam(Class<?> klass, int index) { Type[] types = getTypeParams(klass); if (index >= 0 && index < types.length) { Type t = types[index]; Class<T> clazz = (Class<T>) Lang.getTypeClass(t); if (clazz == null) throw Lang.makeThrow("Type '%s' is not a Class", t.toString()); return clazz; } throw Lang.makeThrow("Class type param out of range %d/%d", index, types.length); }
protected List<Sql> createIndexs(Entity<?> en) { List<Sql> sqls = new ArrayList<Sql>(); StringBuilder sb = new StringBuilder(); List<EntityIndex> indexs = en.getIndexes(); for (EntityIndex index : indexs) { sb.setLength(0); if (index.isUnique()) sb.append("Create UNIQUE Index "); else sb.append("Create Index "); if (index.getName().contains("$")) sb.append(TableName.render(new CharSegment(index.getName()))); else sb.append(index.getName()); sb.append(" ON ").append(en.getTableName()).append("("); for (EntityField field : index.getFields()) { if (field instanceof MappingField) { MappingField mf = (MappingField) field; sb.append(mf.getColumnNameInSql()).append(','); } else { throw Lang.makeThrow( DaoException.class, "%s %s is NOT a mapping field, can't use as index field!!", en.getClass(), field.getName()); } } sb.setCharAt(sb.length() - 1, ')'); sqls.add(Sqls.create(sb.toString())); } return sqls; }
/** * 根据一个字段名和字段类型获取 Setter * * @param fieldName 字段名 * @param paramType 字段类型 * @return 方法 * @throws NoSuchMethodException 没找到 Setter */ public Method getSetter(String fieldName, Class<?> paramType) throws NoSuchMethodException { try { String setterName = "set" + Strings.capitalize(fieldName); try { return klass.getMethod(setterName, paramType); } catch (Throwable e) { try { return klass.getMethod(fieldName, paramType); } catch (Throwable e1) { Mirror<?> type = Mirror.me(paramType); for (Method method : klass.getMethods()) { if (method.getParameterTypes().length == 1) if (method.getName().equals(setterName) || method.getName().equals(fieldName)) { if (null == paramType || type.canCastToDirectly(method.getParameterTypes()[0])) return method; } } // 还是没有? 会不会是包装类型啊? if (!paramType.isPrimitive()) { Class<?> p = unWrapper(); if (null != p) return getSetter(fieldName, p); } throw new RuntimeException(); } } } catch (Throwable e) { throw Lang.makeThrow( NoSuchMethodException.class, "Fail to find setter for [%s]->[%s(%s)]", klass.getName(), fieldName, paramType.getName()); } }
public static SqlExpression create(String name, String op, Object value) { op = Strings.trim(op.toUpperCase()); // NULL if (null == value) { SqlExpression re; // IS NULL if ("IS".equals(op) || "NOT IS".equals(op) || "IS NOT".equals(op)) { re = isNull(name); } // !!! else { throw Lang.makeThrow("null can only use 'IS' or 'NOT IS'"); } return re.setNot(op.startsWith("NOT") || op.endsWith("NOT")); } // IN else if ("IN".equals(op) || "NOT IN".equals(op)) { Class<?> type = value.getClass(); SqlExpression re; // 数组 if (type.isArray()) { re = _evalRange((Mirror<?>) Mirror.me(type.getComponentType()), name, value); } // 集合 else if (Collection.class.isAssignableFrom(type)) { Object first = Lang.first(value); if (null == first) return null; re = _evalRange((Mirror<?>) Mirror.me(first), name, value); } // Sql Range else { re = inSql(name, value.toString()); } return re.setNot(op.startsWith("NOT")); } // LIKE || IS else if ("LIKE".equals(op) || "NOT LIKEs".equals(op)) { String v = value.toString(); Like re; if (v.length() == 1) { re = like(name, v); } else { re = like(name, v.substring(1, v.length() - 1)); re.left(v.substring(0, 1)); re.right(v.substring(v.length() - 1, v.length())); } return re.ignoreCase(false).setNot(op.startsWith("NOT")); } // = else if ("=".equals(op)) { return eq(name, value); } // != else if ("!=".equals(op) || "<>".equals(op)) { // TODO 检查一下,原本是&&, 明显永远成立 return eq(name, value).setNot(true); } // Others return new SimpleExpression(name, op, value); }
/** * @return 获得外覆类 * @throws RuntimeException 如果当前类型不是原生类型,则抛出 */ public Class<?> getWrapperClass() { if (!klass.isPrimitive()) { if (this.isPrimitiveNumber() || this.is(Boolean.class) || this.is(Character.class)) return klass; throw Lang.makeThrow("Class '%s' should be a primitive class", klass.getName()); } // TODO 用散列能快一点 if (is(int.class)) return Integer.class; if (is(char.class)) return Character.class; if (is(boolean.class)) return Boolean.class; if (is(long.class)) return Long.class; if (is(float.class)) return Float.class; if (is(byte.class)) return Byte.class; if (is(short.class)) return Short.class; if (is(double.class)) return Double.class; throw Lang.makeThrow("Class [%s] has no wrapper class!", klass.getName()); }
/** * 获取colName所在的行数 * * @param meta 从连接中取出的ResultSetMetaData * @param colName 字段名 * @return 所在的索引,如果不存在就抛出异常 * @throws SQLException 指定的colName找不到 */ public static int getColumnIndex(ResultSetMetaData meta, String colName) throws SQLException { if (meta == null) return 0; int columnCount = meta.getColumnCount(); for (int i = 1; i <= columnCount; i++) if (meta.getColumnName(i).equalsIgnoreCase(colName)) return i; // TODO 尝试一下meta.getColumnLabel? log.infof("Can not find @Column(%s) in table/view (%s)", colName, meta.getTableName(1)); throw Lang.makeThrow(SQLException.class, "Can not find @Column(%s)", colName); }
/** * 子类复写:修改 get 后的值,以便设置给 DBObject * * <p>如果不是严格检查的话, adaptor 如果发现自己不能接受这个类型,则可以直接返回输入的对象 * * @param val get 后的值 * @param check 是否严格检查 * @return 修改 get 后的值,这个值是 ejecting 从对象中取出的 */ public Object adaptForGet(Object val, boolean check) { if (null != val && CoIdType.DEFAULT == field.getIdType() && !(val instanceof ObjectId)) { String s = val.toString(); if (!Mongos.isDefaultMongoId(s)) throw Lang.makeThrow("Expect Mongo ID format, but is was '%s'", s); return new ObjectId(s); } return val; }
public String evalFieldType(MappingField mf) { if (mf.getCustomDbType() != null) return mf.getCustomDbType(); switch (mf.getColumnType()) { case CHAR: return "CHAR(" + mf.getWidth() + ")"; case BOOLEAN: return "BOOLEAN"; case VARCHAR: return "VARCHAR(" + mf.getWidth() + ")"; case TEXT: return "TEXT"; case BINARY: return "BLOB"; case TIMESTAMP: return "TIMESTAMP"; case DATETIME: return "DATETIME"; case DATE: return "DATE"; case TIME: return "TIME"; case INT: // 用户自定义了宽度 if (mf.getWidth() > 0) return "INT(" + mf.getWidth() + ")"; // 用数据库的默认宽度 return "INT"; case FLOAT: // 用户自定义了精度 if (mf.getWidth() > 0 && mf.getPrecision() > 0) { return "NUMERIC(" + mf.getWidth() + "," + mf.getPrecision() + ")"; } // 用默认精度 if (mf.getTypeMirror().isDouble()) return "NUMERIC(15,10)"; return "FLOAT"; case PSQL_ARRAY: return "ARRAY"; case PSQL_JSON: case MYSQL_JSON: return "JSON"; // TODO 这里不用加 default 么 } throw Lang.makeThrow( "Unsupport colType '%s' of field '%s' in '%s' ", mf.getColumnType(), mf.getName(), mf.getEntity().getType().getName()); }
private void _runPreparedStatement(Connection conn, DaoStatement st, Object[][] paramMatrix) throws SQLException { ValueAdaptor[] adaptors = st.getAdaptors(); if (adaptors.length != paramMatrix[0].length) throw Lang.makeThrow("DaoStatement adaptor MUST same width with param matrix."); boolean statIsClosed = false; String sql = st.toPreparedStatement(); PreparedStatement pstat = null; // 打印调试信息 if (log.isDebugEnabled()) log.debug(st); try { // 创建 SQL 语句 pstat = conn.prepareStatement(sql); // 就一条记录,不要批了吧 if (paramMatrix.length == 1) { for (int i = 0; i < paramMatrix[0].length; i++) { adaptors[i].set(pstat, paramMatrix[0][i], i + 1); } pstat.execute(); st.getContext().setUpdateCount(pstat.getUpdateCount()); pstat.close(); statIsClosed = true; } // 恩,批 else { for (Object[] params : paramMatrix) { for (int i = 0; i < params.length; i++) { adaptors[i].set(pstat, params[i], i + 1); } pstat.addBatch(); // 需要配置一下batchSize,嘻嘻,不然分分钟爆内存!! } int[] counts = pstat.executeBatch(); // 计算总共影响的行数 int sum = 0; for (int i : counts) if (i > 0) sum += i; if (sum == 0) sum = pstat.getUpdateCount(); pstat.close(); statIsClosed = true; st.getContext().setUpdateCount(sum); } } finally { if (!statIsClosed) Daos.safeClose(pstat); } // 打印更详细的调试信息 if (log.isTraceEnabled()) log.trace("...DONE"); }
private static <T extends Map<Object, Object>> Map<Object, Object> createMap(Class<T> mapClass) { Map<Object, Object> map; try { map = mapClass.newInstance(); } catch (Exception e) { map = new HashMap<Object, Object>(); } if (!mapClass.isAssignableFrom(map.getClass())) { throw Lang.makeThrow("Fail to create map [%s]", mapClass.getName()); } return map; }
/** * 执行一个特殊的Chain(事实上普通Chain也能执行,但不建议使用) * * @see org.nutz.dao.Chain#addSpecial(String, Object) */ @SuppressWarnings({"rawtypes"}) public static void insertBySpecialChain(Dao dao, Entity en, String tableName, Chain chain) { if (en != null) tableName = en.getTableName(); if (tableName == null) throw Lang.makeThrow(DaoException.class, "tableName and en is NULL !!"); final StringBuilder sql = new StringBuilder("INSERT INTO ").append(tableName).append(" ("); StringBuilder _value_places = new StringBuilder(" VALUES("); final List<Object> values = new ArrayList<Object>(); final List<ValueAdaptor> adaptors = new ArrayList<ValueAdaptor>(); Chain head = chain.head(); while (head != null) { String colName = head.name(); MappingField mf = null; if (en != null) { mf = en.getField(colName); if (mf != null) colName = mf.getColumnName(); } sql.append(colName); if (head.special()) { _value_places.append(head.value()); } else { if (en != null) mf = en.getField(head.name()); _value_places.append("?"); values.add(head.value()); ValueAdaptor adaptor = Jdbcs.getAdaptorBy(head.value()); if (mf != null && mf.getAdaptor() != null) adaptor = mf.getAdaptor(); adaptors.add(adaptor); } head = head.next(); if (head != null) { sql.append(", "); _value_places.append(", "); } } sql.append(")"); _value_places.append(")"); sql.append(_value_places); if (log.isDebugEnabled()) log.debug(sql); dao.run( new ConnCallback() { public void invoke(Connection conn) throws Exception { PreparedStatement ps = conn.prepareStatement(sql.toString()); try { for (int i = 0; i < values.size(); i++) adaptors.get(i).set(ps, values.get(i), i + 1); ps.execute(); } finally { Daos.safeClose(ps); } } }); }
public Map<String, Object> getReferObject( ServletContext sc, HttpServletRequest request, HttpServletResponse response, String[] pathArgs) { try { if (!"POST".equals(request.getMethod()) && !"PUT".equals(request.getMethod())) { String str = "Not POST or PUT, Wrong HTTP method! --> " + request.getMethod(); throw Lang.makeThrow(IllegalArgumentException.class, str); } // 看看是不是传统的上传 String contentType = request.getContentType(); if (contentType == null) { throw Lang.makeThrow(IllegalArgumentException.class, "Content-Type is NULL!!"); } if (contentType.contains("multipart/form-data")) { // 普通表单上传 if (log.isDebugEnabled()) log.debug("Select Html4 Form upload parser --> " + request.getRequestURI()); Uploading ing = new FastUploading(); return ing.parse(request, context); } if (contentType.contains("application/octet-stream")) { // Html5 // 流式上传 if (log.isDebugEnabled()) log.debug("Select Html5 Stream upload parser --> " + request.getRequestURI()); Uploading ing = new Html5Uploading(); return ing.parse(request, context); } // 100%是没写enctype='multipart/form-data' if (contentType.contains("application/x-www-form-urlencoded")) { log.warn("Using form upload ? You forgot this --> enctype='multipart/form-data' ?"); } throw Lang.makeThrow(IllegalArgumentException.class, "Unknow Content-Type : " + contentType); } catch (UploadException e) { throw Lang.wrapThrow(e); } finally { Uploads.removeInfo(request); } }
public Object eject(Object obj) { try { return null == obj ? null : getter.invoke(obj); } catch (InvocationTargetException e) { throw new FailToGetValueException("getter=" + getter, e); } catch (Exception e) { if (log.isInfoEnabled()) log.info("Fail to value by getter", e); throw Lang.makeThrow( "Fail to invoke getter %s.'%s()' because [%s]: %s", getter.getDeclaringClass().getName(), getter.getName(), Lang.unwrapThrow(e), Lang.unwrapThrow(e).getMessage()); } }
/** * 根据名称获取一个 Getter。 * * <p>比如,你想获取 abc 的 getter ,那么优先查找 getAbc(),如果没有则查找isAbc(),最后才是查找 abc()。 * * @param fieldName * @return 方法 * @throws NoSuchMethodException 没有找到 Getter */ public Method getGetter(String fieldName) throws NoSuchMethodException { String fn = Strings.capitalize(fieldName); String _get = "get" + fn; String _is = "is" + fn; for (Method method : klass.getMethods()) { if (method.getParameterTypes().length != 0) continue; if (_get.equals(method.getName())) return method; if (_is.equals(method.getName())) { if (!Mirror.me(method.getReturnType()).isBoolean()) throw new NoSuchMethodException(); return method; } if (fieldName.equals(method.getName())) return method; } throw Lang.makeThrow( NoSuchMethodException.class, "Fail to find getter for [%s]->[%s]", klass.getName(), fieldName); }
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws DisabledAccountException { OAuthToken oauthToken = (OAuthToken) token; Profile credential = oauthToken.getCredentials(); String openid = credential.getValidatedId(); throw Lang.makeThrow(LockedAccountException.class, "Account [ %s ] is locked.", openid); /*Sys_user user = getUserService().fetchByOpenID(openid); if (Lang.isEmpty(user)) { boolean isUpdated = StringUtils.isNotBlank(credential.getDisplayName()); String nickName = StringUtils.defaultString(credential.getDisplayName(), openid); String providerid = credential.getProviderId(); //user = getUserService().initUser(nickName, openid, providerid, oauthToken.getAddr(), isUpdated); } //if (user.isLocked()) { //throw Lang.makeThrow(LockedAccountException.class, "Account [ %s ] is locked.", user.getName()); //} //oauthToken.setRname(!user.isUpdated()); oauthToken.setUserId(openid); SimpleAuthenticationInfo account = new SimpleAuthenticationInfo(user, credential, getName()); oauthToken.getSession().setAttribute(org.nutz.web.Webs.ME, user); return account;*/ }
public static View evalView(NutConfig config, ActionInfo ai, String viewType) { if (Strings.isBlank(viewType)) return new VoidView(); String str = viewType; int pos = str.indexOf(':'); String type, value; if (pos > 0) { type = Strings.trim(str.substring(0, pos).toLowerCase()); value = Strings.trim(pos >= (str.length() - 1) ? null : str.substring(pos + 1)); } else { type = str; value = null; } for (ViewMaker maker : ai.getViewMakers()) { if (maker instanceof ViewMaker2) { View view = ((ViewMaker2) maker).make(config, ai, type, value); if (view != null) return view; } View view = maker.make(config.getIoc(), type, value); if (null != view) return view; } throw Lang.makeThrow("Can not eval %s(\"%s\") View for %s", viewType, str, ai.getMethod()); }
private static final IocException duplicateField(Class<?> classZ, String name) { return Lang.makeThrow( IocException.class, "Duplicate filed defined! Class=%s,FileName=%s", classZ, name); }
/** * 执行一个特殊的Chain(事实上普通Chain也能执行,但不建议使用) * * @see org.nutz.dao.Chain#addSpecial(String, Object) */ @SuppressWarnings({"rawtypes"}) public static int updateBySpecialChain( Dao dao, Entity en, String tableName, Chain chain, Condition cnd) { if (en != null) tableName = en.getTableName(); if (tableName == null) throw Lang.makeThrow(DaoException.class, "tableName and en is NULL !!"); final StringBuilder sql = new StringBuilder("UPDATE ").append(tableName).append(" SET "); Chain head = chain.head(); final List<Object> values = new ArrayList<Object>(); final List<ValueAdaptor> adaptors = new ArrayList<ValueAdaptor>(); while (head != null) { MappingField mf = null; if (en != null) mf = en.getField(head.name()); String colName = head.name(); if (mf != null) colName = mf.getColumnName(); sql.append(colName).append("="); if (head.special()) { if (head.value() != null && head.value() instanceof String) { String str = (String) head.value(); if (str.length() > 0) { switch (str.charAt(0)) { case '+': case '-': case '*': case '/': case '%': case '&': case '^': case '|': sql.append(colName); break; } } } sql.append(head.value()); } else { sql.append("?"); values.add(head.value()); ValueAdaptor adaptor = Jdbcs.getAdaptorBy(head.value()); if (mf != null && mf.getAdaptor() != null) adaptor = mf.getAdaptor(); adaptors.add(adaptor); } sql.append(" "); head = head.next(); if (head != null) sql.append(", "); } if (cnd != null) sql.append(" ").append(cnd.toSql(en)); if (log.isDebugEnabled()) log.debug(sql); final int[] ints = new int[1]; dao.run( new ConnCallback() { public void invoke(Connection conn) throws Exception { PreparedStatement ps = conn.prepareStatement(sql.toString()); try { for (int i = 0; i < values.size(); i++) adaptors.get(i).set(ps, values.get(i), i + 1); ints[0] = ps.executeUpdate(); } finally { Daos.safeClose(ps); } } }); return ints[0]; }
private Tmpl(String tmpl, Pattern ptn, int groupIndex) { this(ptn, groupIndex); // 开始解析 Matcher m = _P.matcher(tmpl); int lastIndex = 0; while (m.find()) { int pos = m.start(); // 看看是否要生成静态对象 if (pos > lastIndex) { list.add(new TmplStaticEle(tmpl.substring(lastIndex, pos))); } // 分析键 Matcher m2 = _P2.matcher(m.group(this.groupIndex)); if (!m2.find()) throw Lang.makeThrow("Fail to parse tmpl key '%s'", m.group(1)); String key = m2.group(1); String type = Strings.sNull(m2.group(3), "string"); String fmt = m2.group(5); String dft = m2.group(7); // 记录键 keys.add(key); // 创建元素 if ("string".equals(type)) { list.add(new TmplStringEle(key, dft)); } // int else if ("int".equals(type)) { list.add(new TmplIntEle(key, fmt, dft)); } // long else if ("long".equals(type)) { list.add(new TmplLongEle(key, fmt, dft)); } // boolean else if ("boolean".equals(type)) { list.add(new TmplBooleanEle(key, fmt, dft)); } // float else if ("float".equals(type)) { list.add(new TmplFloatEle(key, fmt, dft)); } // double else if ("double".equals(type)) { list.add(new TmplDoubleEle(key, fmt, dft)); } // date else if ("date".equals(type)) { list.add(new TmplDateEle(key, fmt, dft)); } // 靠不可能 else { throw Lang.impossible(); } // 记录 lastIndex = m.end(); } // 最后结尾是否要加入一个对象 if (!(lastIndex >= tmpl.length())) { list.add(new TmplStaticEle(tmpl.substring(lastIndex))); } }
private void addClass(Class<?> classZ) { if (classZ.isInterface() || classZ.isMemberClass() || classZ.isEnum() || classZ.isAnnotation() || classZ.isAnonymousClass()) return; int modify = classZ.getModifiers(); if (Modifier.isAbstract(modify) || (!Modifier.isPublic(modify))) return; IocBean iocBean = classZ.getAnnotation(IocBean.class); if (iocBean != null) { if (log.isDebugEnabled()) log.debugf("Found a Class with Ioc-Annotation : %s", classZ); // 采用 @IocBean->name String beanName = iocBean.name(); if (Strings.isBlank(beanName)) { // 否则采用 @InjectName InjectName innm = classZ.getAnnotation(InjectName.class); if (null != innm && !Strings.isBlank(innm.value())) { beanName = innm.value(); } // 大哥(姐),您都不设啊!? 那就用 simpleName 吧 else { beanName = Strings.lowerFirst(classZ.getSimpleName()); } } if (map.containsKey(beanName)) throw Lang.makeThrow( IocException.class, "Duplicate beanName=%s, by %s !! Have been define by %s !!", beanName, classZ, map.get(beanName).getClass()); IocObject iocObject = new IocObject(); iocObject.setType(classZ); map.put(beanName, iocObject); iocObject.setSingleton(iocBean.singleton()); if (!Strings.isBlank(iocBean.scope())) iocObject.setScope(iocBean.scope()); // 看看构造函数都需要什么函数 String[] args = iocBean.args(); // if (null == args || args.length == 0) // args = iocBean.param(); if (null != args && args.length > 0) for (String value : args) iocObject.addArg(convert(value)); // 设置Events IocEventSet eventSet = new IocEventSet(); iocObject.setEvents(eventSet); if (!Strings.isBlank(iocBean.create())) eventSet.setCreate(iocBean.create().trim().intern()); if (!Strings.isBlank(iocBean.depose())) eventSet.setDepose(iocBean.depose().trim().intern()); if (!Strings.isBlank(iocBean.fetch())) eventSet.setFetch(iocBean.fetch().trim().intern()); // 处理字段(以@Inject方式,位于字段) List<String> fieldList = new ArrayList<String>(); Mirror<?> mirror = Mirror.me(classZ); Field[] fields = mirror.getFields(Inject.class); for (Field field : fields) { Inject inject = field.getAnnotation(Inject.class); // 无需检查,因为字段名是唯一的 // if(fieldList.contains(field.getName())) // throw duplicateField(classZ,field.getName()); IocField iocField = new IocField(); iocField.setName(field.getName()); IocValue iocValue; if (Strings.isBlank(inject.value())) { iocValue = new IocValue(); iocValue.setType(IocValue.TYPE_REFER); iocValue.setValue(field.getName()); } else iocValue = convert(inject.value()); iocField.setValue(iocValue); iocObject.addField(iocField); fieldList.add(iocField.getName()); } // 处理字段(以@Inject方式,位于set方法) Method[] methods; try { methods = classZ.getMethods(); } catch (Exception e) { // 如果获取失败,就忽略之 log.info("Fail to call getMethods(), miss class or Security Limit, ignore it", e); methods = new Method[0]; } for (Method method : methods) { Inject inject = method.getAnnotation(Inject.class); if (inject == null) continue; // 过滤特殊方法 int m = method.getModifiers(); if (Modifier.isAbstract(m) || (!Modifier.isPublic(m)) || Modifier.isStatic(m)) continue; String methodName = method.getName(); if (methodName.startsWith("set") && methodName.length() > 3 && method.getParameterTypes().length == 1) { IocField iocField = new IocField(); iocField.setName(Strings.lowerFirst(methodName.substring(3))); if (fieldList.contains(iocField.getName())) throw duplicateField(classZ, iocField.getName()); IocValue iocValue; if (Strings.isBlank(inject.value())) { iocValue = new IocValue(); iocValue.setType(IocValue.TYPE_REFER); iocValue.setValue(Strings.lowerFirst(methodName.substring(3))); } else iocValue = convert(inject.value()); iocField.setValue(iocValue); iocObject.addField(iocField); fieldList.add(iocField.getName()); } } // 处理字段(以@IocBean.field方式) String[] flds = iocBean.fields(); if (flds != null && flds.length > 0) { for (String fieldInfo : flds) { if (fieldList.contains(fieldInfo)) throw duplicateField(classZ, fieldInfo); IocField iocField = new IocField(); if (fieldInfo.contains(":")) { // dao:jndi:dataSource/jdbc形式 String[] datas = fieldInfo.split(":", 2); // 完整形式, 与@Inject完全一致了 iocField.setName(datas[0]); iocField.setValue(convert(datas[1])); iocObject.addField(iocField); } else { // 基本形式, 引用与自身同名的bean iocField.setName(fieldInfo); IocValue iocValue = new IocValue(); iocValue.setType(IocValue.TYPE_REFER); iocValue.setValue(fieldInfo); iocField.setValue(iocValue); iocObject.addField(iocField); } fieldList.add(iocField.getName()); } } } else { if (log.isWarnEnabled()) { Field[] fields = classZ.getDeclaredFields(); for (Field field : fields) if (field.getAnnotation(Inject.class) != null) { log.warnf( "class(%s) don't has @IocBean, but field(%s) has @Inject! Miss @IocBean ??", classZ.getName(), field.getName()); break; } } } }