la inyección de constructor en la clase abstracta e hijos

prettyvoid:

Tengo una clase de la siguiente

@Component
public abstract class NotificationCenter {
    protected final EmailService emailService;
    protected final Logger log = LoggerFactory.getLogger(getClass());

    protected NotificationCenter(EmailService emailService) {
        this.emailService = emailService;
    }

    protected void notifyOverEmail(String email, String message) {
        //do some work
        emailService.send(email, message);
    }
}

EmailServicees una @Servicey debe ser auto-cableado por inyección de constructor.

Ahora tengo una clase que se extiende NotificationCentery también debe componentes auto-alambre

@Service
public class NotificationCenterA extends NotificationCenter {    
    private final TemplateBuildingService templateBuildingService;

    public NotificationCenterA(TemplateBuildingService templateBuildingService) {
        this.templateBuildingService = templateBuildingService;
    }
}

Basado en el ejemplo anterior, el código no se compilará porque no hay ningún constructor predeterminado de la clase abstracta NotificationCentera menos agrego super(emailService);que la primera declaración de NotificationCenterAconstructor, pero no tengo una instancia de la emailServicey no tengo la intención de poblar la base campo de los niños.

Cualquier idea de lo que es la forma correcta de manejar esta situación? Tal vez debería usar la inyección de campo?

Marcos Bramnik:

NotificationCenterNo es una clase real, sino una clase abstracta, por lo que no se puede crear la instancia de la misma. Por otro lado, tiene un campo (campo final!) EmailServiceQue tiene que ser inicializado en el constructor! Setter no funcionará aquí, debido a que el campo final se inicializa exactamente una vez. Es Java, ni siquiera la primavera.

Cualquier clase que se extiende NotificationCenter hereda la EmailService campo porque este niño "es un" centro de notificación

Por lo tanto, tiene que proporcionar un constructor que recibe la instancia de servicio de correo electrónico y lo pasa al súper para la inicialización. Es más, Java, no de Primavera.

public class NotificationCenterA extends NotificationCenter {    
    private final TemplateBuildingService templateBuildingService;

    public NotificationCenterA(EmailService emailService, TemplateBuildingService templateBuildingService) {
       super(emailService);
       this.templateBuildingService = templateBuildingService;
    }
} 

Ahora la primavera gestiona los granos para usted, les inyecta inicializa y las dependencias. Usted escribe algo que francamente no entiendo:

... como la primera declaración a NotificationCenterA constructor, pero no tengo una instancia de la emailService y no tengo la intención de poblar el campo de base de los niños.

Pero la primavera administrará solamente un NotificationCenterAfrijol (y por supuesto la aplicación EmailService), no logra la clase abstracta, y desde Java pone las restricciones (por una razón) descrito anteriormente, creo que la respuesta directa a su pregunta será:

  1. No se puede utilizar la inyección colocador en este caso (de nuevo, debido a la final, es Java, no a causa de la primavera)
  2. la inyección de constructor, estando en un caso general mejor que la inyección colocador puede manejar con exactitud su caso

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=177866&siteId=1
Recomendado
Clasificación