通过反射迭代对象的集合属性

时间:2015-08-28 22:16:21

标签: java reflection

我正在尝试在我的代码中实现关于级联保存在spring数据mongodb中的this解决方案。它适用于这样的普通类。

android-support-v*.jar

但我有类似的东西。

public class Test{

    @Id
    private String id;

    @DBRef
    @CascadeSave
    private Contact contact;
}

我想更改public class Test{ @Id private String id; @DBRef @CascadeSave private Set<Contact> contacts = new HashSet<>(); } 中的listener中的代码,该代码位于link中,用于处理集合。我尝试了几件事但没有成功。除此之外,如果有另一种方式完成这项任务,即使这是一个单独的问题,我们将不胜感激。

我在下面给出的监听器代码,与示例链接没什么区别。

public class CascadingMongoEventListener extends AbstractMongoEventListener {

private static final Logger logger = LoggerFactory.getLogger(CascadingMongoEventListener.class);

@Autowired
private MongoOperations mongoOperations;

@Override
public void onBeforeConvert(final Object source) {
     ReflectionUtils.doWithFields(source.getClass(), new ReflectionUtils.FieldCallback() {

        public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
            ReflectionUtils.makeAccessible(field);
            try {
                if (field.isAnnotationPresent(DBRef.class) && field.isAnnotationPresent(CascadeSave.class)) {
                    final Object fieldValue = field.get(source);
                    if (fieldValue != null) {

                        if (Collection.class.isAssignableFrom(field.getType())) {
                            @SuppressWarnings("unchecked")
                            Collection models = (Collection) fieldValue;
                            for (Object model : models) {
                               mongoOperations.save(model);
                            }
                        } else {
                            mongoOperations.save(fieldValue);
                        }
                    }
                }
            } catch (Exception e) {
                logger.error(e.getMessage());
                e.printStackTrace();
            }
        }
    });
}

private static class DbRefFieldCallback implements ReflectionUtils.FieldCallback {
    private boolean idFound;

    public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
        ReflectionUtils.makeAccessible(field);
        if (field.isAnnotationPresent(Id.class)) {
            idFound = true;
        }
    }

    public boolean isIdFound() {
        return idFound;
    }
}
}

1 个答案:

答案 0 :(得分:0)

这是对我有用的解决方案,我将不胜感激任何建议。

public class CascadingMongoEventListener extends AbstractMongoEventListener {

private static final Logger logger = LoggerFactory.getLogger(CascadingMongoEventListener.class);
@Autowired
private MongoOperations mongoOperations;

@Override
public void onBeforeConvert(final Object source) {
    ReflectionUtils.doWithFields(source.getClass(), new ReflectionUtils.FieldCallback() {

        public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
            ReflectionUtils.makeAccessible(field);

            if (field != null) {
                Object fieldValue = field.get(source);
                if (field.isAnnotationPresent(DBRef.class) && field.isAnnotationPresent(CascadeSave.class)) {
                    if (Collection.class.isAssignableFrom(fieldValue.getClass())) {
                        Collection<Object> collection = (Collection<Object>) fieldValue;
                        for (Object item : collection) {
                            if (mongoOperations.collectionExists(item.getClass())) {
                                mongoOperations.save(item);
                                logger.debug("Set of {}s saved.", item.getClass().getSimpleName());
                            }
                        }
                    } else {
                        if (mongoOperations.collectionExists(fieldValue.getClass())) {
                            mongoOperations.save(fieldValue);
                            logger.debug("{} saved.", fieldValue.getClass().getSimpleName());
                        }
                    }
                }
            }
        }
    });
  }
}