Spring - внедрить список ссылок на bean-объекты с наследованием. У бобов есть @Transactional внутри - PullRequest
0 голосов
/ 24 марта 2020

Вот мой фабричный метод для возврата заданной c службы на основе OrderType.

@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ServiceFactory {
    private final List<SettlementService> serviceList;
    private Map<OrderType, SettlementService> settlementServiceMap;

    @PostConstruct
    public void initFactory(){
        //Don't bother here. Will populate the map properly, when it works.
        //this.settlementServiceMap = new EnumMap<OrderType, SettlementService>(OrderType.class);
        //this.settlementServiceMap.put(CUSTOMER_ORDER, customerService);
        //this.settlementServiceMap.put(CLIENT_DEBIT_ORDER, clientService);
        //this.settlementServiceMap.put(CLIENT_CREDIT_ORDER, clientService);
    }

    public SettlementService provideService(OrderType orderType){
        Optional<SettlementService> settlementService = Optional.ofNullable(settlementServiceMap.get(orderType));
        if (!settlementService.isPresent()){
            throw new ApplicationException("Wrong order type");
        }

        return settlementService.get();
    }
}

Пример реализации такой службы:

@Component
public class CustomerService extends AbstractSettlementService implements SettlementService {

    private final OrderDAO orderDAO;
    private final OrderValidationService orderValidationService;

    @Autowired
    public CustomerService (OrderDAO orderDAO, OrderValidationService orderValidationService, SynchronizationService synchronizationService) {
        super(synchronizationService);
        this.orderDAO = orderDAO;
        this.orderValidationService = orderValidationService;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Throwable.class)
    public void settleOperation(Order order) {
        this.someMethod(order);
        super.addEvents(order.getAccountId());
    }
}

Абстрактный класс:

@RequiredArgsConstructor
public abstract class AbstractSettlementService  implements SettlementService {

    private final SynchronizationService synchronizationService;

    public void addEvents(Long accountId){
        synchronizationService.registerEvent(accountId);
    }
}

И интерфейс:

public interface SettlementService{

    void someMethod(Order order);
}

Я продолжаю получать:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [company.com.ServiceFactory]: Illegal arguments for constructor; nested exception is java.lang.IllegalArgumentException: argument type mismatch
Caused by: java.lang.IllegalArgumentException: argument type mismatch"}}

Насколько я знаю, когда @Autowiring коллекция, все объекты этот тип должен быть введен в коллекцию. С аннотацией @Transactional создается прокси, который должен реализовывать SettlementService, поэтому не должно быть проблем с добавлением 2 сервисов в список. Что мне не хватает?

Я пытался: - заменить список двумя отдельными компонентами служб с @Qualifier аннотацией (та же ошибка) - заменить @RequiredArgsConstructor на @Autowired аннотированный установщик

I также есть <context:component-scan base-package="com.company.myPackage"/> в бобах. xml, указывающий на правильный пакет.

...