Printemps et en classe Abstraite - l'injection de propriétés dans les classes abstraites

j'ai une classe de base abstraite avec une propriété appelée" mailserver " que je souhaite injecter à partir du conteneur de printemps du CIO. Cependant, lorsque j'exécute les implémentations concrètes de la classe abstract, j'obtiens un null pour la propriété mailserver.

Quelle est la bonne façon de procéder? As-tu essayé de faire quelque chose comme ça et tu as réussi? S'il vous plaît partager.

concerne khush.

13
demandé sur Khushroo Mistry 2011-08-25 06:43:15

3 réponses

marquer la définition de la classe de base abstraite en tant qu'Abrégé en utilisant l'attribut abstract , et dans la définition de la classe de béton , faire de l'attribut parent le nom de la classe de base abstraite

quelque chose comme ça:

<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>
11
répondu Ken Chan 2011-08-25 03:09:36

Propriétés dans les superclasses, abstraites ou non, sont injectées exactement les mêmes que toutes les autres propriétés au printemps. Vous pouvez utiliser setter, constructor, ou field injection basé sur XML, annotations, ou Java config. Vous trouverez une large utilisation de l'héritage tout au long du printemps: le DefaultMessageListenerContainer , par exemple. Montrez comment vous essayez de transférer la propriété, et quelqu'un peut vous donner une explication de la raison pour laquelle cela ne fonctionne pas.

2
répondu Ryan Stewart 2011-08-25 03:16:07

dans mon cas, à l'intérieur D'une application Spring4, j'ai dû utiliser un modèle D'usine abstrait classique (pour lequel j'ai pris l'idée de - http://java-design-patterns.com/patterns/abstract-factory / ) pour créer des instances à chaque fois qu'il y avait une opération à faire.Donc mon code devait être conçu comme:

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);
    }
}

initialement pour injecter les dépendances dans la classe abstraite j'ai essayé toutes les annotations stéréotypées comme @Component, @Service etc mais même si Spring context file avait ComponentScanning pour L'ensemble du paquet, mais d'une manière ou d'une autre tout en créant des instances de sous-classes comme CampaignOperation, la classe super Abstract EO avait null pour ses propriétés car spring était incapable de reconnaître et d'injecter ses dépendances.Après beaucoup d'essais et d'erreurs j'ai utilisé cette annotation **@Configurable(dependencyCheck = true)** et finalement Spring a pu injecter les dépendances et j'ai pu utiliser les propriétés dans la sous-classe sans les encombrer avec trop de propriété.

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

j'ai aussi essayé ces autres références pour trouver une solution:

  1. http://www.captaindebug.com/2011/06/implementing-springs-factorybean.html#.WqF5pJPwaAN
  2. http://forum.spring.io/forum/spring-projects/container/46815-problem-with-autowired-in-abstract-class
  3. https://github.com/cavallefano/Abstract-Factory-Pattern-Spring-Annotation
  4. http://www.jcombat.com/spring/factory-implementation-using-servicelocatorfactorybean-in-spring
  5. https://www.madbit.org/blog/programming/1074/1074/#sthash.XEJXdIR5.dpbs
  6. Utilisation de résumé d'usine avec le framework Spring
  7. Printemps permettra à l'autowiring pas de travail pour les classes Abstraites
  8. Injecter du printemps de la dépendance en résumé super classe
  9. dépendance au ressort défini dans une classe abstraite
    1. Printemps peut vous autowire à l'intérieur d'une classe abstraite?

s'il vous Plaît essayez d'utiliser **@Configurable(dependencyCheck = true)** et mise à jour de ce post, je pourrais essayer de vous aider si vous rencontrez des problèmes.

0
répondu user1295235 2018-03-09 23:17:30