Авто-проводные хранилища с отражением - PullRequest
0 голосов
/ 05 ноября 2018

Я пытаюсь достучаться до своих репозиториев, чтобы уменьшить сложность чтения в проекте. Я должен кешировать 3 таблицы БД с учетом cacheTable. Эти таблицы:

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 голосов
/ 05 ноября 2018

Отражение - это последнее, что вам здесь нужно, и оно не улучшит читабельность, но сделает вещи излишне сложными, медленными и трудными для понимания.

Вы можете избежать повторения одного и того же кода трижды, просто используя лучший дизайн ОО. Например, предположим, основываясь на опубликованном вами коде, что ваши 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);
}

В традиционном бизнес-коде рефлексия почти всегда является ужасной идеей. Изучите полиморфизм, структуры данных, шаблоны проектирования: вот те инструменты, которые вы должны использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...