具有反射的自动连线存储库

时间:2018-11-05 19:27:11

标签: java reflection

我试图通过反射进入我的存储库,以减少项目中的可读性。我必须使用cacheTable来缓存3个DB表。这些表是;

I. TEST_PARAMETERS
II。 TEST_REAL_TRANSACTION_CRITERIA
III。 DEV_USER_STDLOV

如果我不使用反射,则必须使用切换用例来根据表名使用存储库,例如:

无反省

@Autowired
private TestCacheListRepository testCacheListRepository;

@Autowired
private TestParametersRepository testParametersRepository;

@Autowired
private TestTransactionCriteriaRepository testTransactionCriteriaRepository;

@Autowired
private DevUserStdlovRepository devUserStdlovRepository;

for (TestCacheListEntity entity : testCacheListEntities) {
            String cacheKey = entity.getCacheKey();

            switch (cacheKey.toLowerCase()) {
                case "test_parameters" :
                    cachedObject.put("test_parameters", new ArrayList<>());
                    for (TestParametersEntity testParametersEntity : testParametersRepository.findAll()) {
                        cachedObject.get("test_parameters").add(testParametersEntity);
                    }
                    break;

                case "test_real_transaction_criteria":
                    cachedObject.put("test_real_transaction_criteria", new ArrayList<>());
                    for (TestRealTransactionCriteriaEntity testRealTransactionCriteriaEntity : testRealTransactionCriteriaRepository.findAll()) {
                        cachedObject.get("test_real_transaction_criteria").add(testRealTransactionCriteriaEntity);
                    }
                    break;

                case "devuser_ngi_stdlov":
                    cachedObject.put("devuser_ngi_stdlov", new ArrayList<>());
                    for (DevUserStdlovEntity devUserStdlovEntity : devUserStdlovRepository.findAll()) {
                        cachedObject.get("devuser_ngi_stdlov").add(devUserStdlovEntity);
                    }
                    break;
            }
        }

另一方面,如果我使用反射,我会得到类似的东西,但是我遇到了问题。

有反思

List<TestCacheListEntity> testCacheListEntities = testCacheListRepository.findAll();

        for (TestCacheListEntity entity : testCacheListEntities) {
            String className = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, entity.getCacheKey()) + "Repository";
            try {
                Class c = Class.forName(className);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

第一个问题是

代码跳入catch块并说

java.lang.ClassNotFoundException: TestParametersRepository

java.lang.ClassNotFoundException: TestRealTransactionCriteriaRepository

java.lang.ClassNotFoundException: DevUserNgiStdlovRepository

我还需要将这些存储库与@Autowired注释一起使用。可以这样使用吗?

谢谢。

1 个答案:

答案 0 :(得分:4)

反射是您在这里需要的最后一件事,它不会提高可读性,但会使事情变得不必要地复杂,缓慢且难以理解。

但是,通过简单地使用更好的OO设计,您可以避免重复三次相同的代码。例如,假设根据您发布的代码,您的3个实体扩展了相同的基类或实现了相同的接口BaseEntity:

private Map<String, Supplier<Collection<? extends BaseEntity>> suppliersByCacheKey = new HashMap<>();

... 

@PostConstruct
void init() {
    suppliersByCacheKey.put("fraud_parameters", () -> fraudParametersRepository.findAll());
    suppliersByCacheKey.put("fraud_real_transaction_criteria", () -> realTransactionCriteriaRepository.findAll());
    suppliersByCacheKey.put("ndvlive_ngi_stdlov", () -> ndvNgiStdlovRepository.findAll());
}
...

for (FraudCacheListEntity entity : fraudCacheListEntities) {
    String cacheKey = entity.getCacheKey();
    List<BaseEntity> listToCache = 
        new ArrayList<>(suppliersByCachKey.get(cacheKey).get());
    cachedObject.put(cacheKey, listToCache);
}

在传统的业务代码中,反射几乎总是一个糟糕的主意。学习多态性,数据结构和设计模式:这些是您应该使用的工具。