Подтвердить что ты не робот

Spring и абстрактный класс - свойства инъекции в абстрактных классах

У меня есть абстрактный базовый класс с свойством, называемым "mailserver", который я хочу вставить из контейнера ioc spring. Однако, когда я запускаю конкретизированные реализации абстрактного класса, я получаю null для свойства mailserver.

Каков правильный способ сделать это? Вы пытались сделать что-то подобное и были успешными? Пожалуйста, поделитесь.

рассматривает khush.

4b9b3361

Ответ 1

Отметьте определение абстрактного базового класса как абстрактное с помощью атрибута abstract и в определении конкретного класса, сделайте атрибут parent именем абстрактного класса bean name

Что-то вроде этого:

<bean id="abstractBaseClass" abstract="true" class="pacakge1.AbstractBaseClass">
  <property name="mailserver" value="DefaultMailServer"/>
</bean>

<bean id="concreteClass1" class="pacakge1.ConcreteClass1" parent="abstractBaseClass">     
  <!--Override the value of the abstract based class if necessary-->
  <property name="mailserver" value="AnotherMailServer"/>
</bean>

Ответ 2

Свойства в суперклассах, абстрактные или нет, вводятся точно так же, как и любые другие свойства в Spring. Вы можете использовать setter, constructor или field injection на основе XML, аннотаций или конфигурации Java. Например, вы найдете широкое использование наследования по Spring: DefaultMessageListenerContainer. Покажите, как вы пытаетесь подключить свойство, и кто-то может дать вам объяснение, почему он не работает.

Ответ 3

В моем случае, в приложении Spring4, мне пришлось использовать классический абстрактный шаблон Factory (для которого я взял идею из - http://java-design-patterns.com/patterns/abstract-factory/), чтобы создавать экземпляры каждый раз, когда выполнялась операция. Поэтому мой код должен был быть сконструирован так:

public abstract class EO {
    @Autowired
    protected SmsNotificationService smsNotificationService;
    @Autowired
    protected SendEmailService sendEmailService;
    ...
    protected abstract void executeOperation(GenericMessage gMessage);
}

public final class OperationsExecutor {
    public enum OperationsType {
        ENROLL, CAMPAIGN
    }

    private OperationsExecutor() {
    }

    public static Object delegateOperation(OperationsType type, Object obj) 
    {
        switch(type) {
            case ENROLL:
                if (obj == null) {
                    return new EnrollOperation();
                }
                return EnrollOperation.validateRequestParams(obj);
            case CAMPAIGN:
                if (obj == null) {
                    return new CampaignOperation();
                }
                return CampaignOperation.validateRequestParams(obj);
            default:
                throw new IllegalArgumentException("OperationsType not supported.");
        }
    }
}

@Configurable(dependencyCheck = true)
public class CampaignOperation extends EO {
    @Override
    public void executeOperation(GenericMessage genericMessage) {
        LOGGER.info("This is CAMPAIGN Operation: " + genericMessage);
    }
}

Изначально для ввода зависимостей в абстрактном классе я пробовал все аннотации стереотипов, такие как @Component, @Service и т.д., но даже несмотря на то, что контекстный файл Spring имел ComponentScanning для всего пакета, но так или иначе при создании экземпляров подклассов, таких как CampaignOperation, Супер абстрактный класс EO имел нуль для своих свойств, поскольку Spring не смог распознать и ввести свои зависимости. После многих проб и ошибок я использовал эту аннотацию **@Configurable(dependencyCheck = true)** и, наконец, Spring смог вставить зависимости, и я смог использовать свойства в подклассе, не загромождая их слишком большим количеством свойств.

<context:annotation-config />
<context:component-scan base-package="com.xyz" />

Я также пробовал эти другие ссылки, чтобы найти решение:

Попробуйте использовать **@Configurable(dependencyCheck = true)** и обновите этот пост, я могу попробовать помочь вам, если у вас возникнут какие-либо проблемы.