2017-05-11 1 views
2

Je développe sur une bibliothèque de base java où le changement est maintenu au minimum, il contient un Foo de classe, où Foo est utilisé par une interface de repos de ressort et autowired dans l'interface de repos.Injection de démarrage de la classe héritée

Je dois étendre Foo pour remplacer l'une de ses méthodes qui est appelée sur Foo.init(), pour modifier un peu l'initiation. Mon FooExtend est autowired d'une autre classe dans mon projet, et j'espère obtenir ces deux pour référencer le même objet, l'objet FooExtend, mais pour l'instant je reçois un objet Foo et un FooExtend. Comment devrais-je résoudre ceci? Les exemples ci-dessous

@Component 
public class Foo{ 
    @PostConstruct 
    private void init() { 
    startStuff(); 
    } 

    protected void startStuff(){ 
    //Stuff done here 
    } 
} 

@Component 
public class FooExtend extends Foo{ 
    @PostConstruct 
    private void init() { 
    //Nothing is done here 
    } 

    @Override 
    protected void startStuff(){ 
    //Different altered stuff is done here 
    } 
} 
+0

Je ne suis pas sûr de comprendre votre problème. Vous avez deux beans, un bean avec le nom "foo" et un bean avec le nom "fooExtend". Il me semble que vous devriez pouvoir utiliser @Qualifier ("fooExtend") ou @Qualifier ("foo") avec @Autowired en plus de référence à Foo pour autowire l'un ou l'autre. – MrKiller21

Répondre

0

Essayez d'exclure de l'analyse de classe Foo de

@ComponentScan(value = {'your.package.here'}, excludeFilters = { 
    @ComponentScan.Filter(classes = { Foo.class }) 
}) 
+0

Je ne peux pas faire des changements comme ceci vers Foo car il est dans le paquet Core et ne devrait donc pas être modifié pour détruire d'autres projets en fonction du noyau. Ou devrais-je le mettre dans mon propre paquet quelque part? –

+0

Vous devriez ajouter ceci sur votre spring-boot (pas dans le paquet de base). Ainsi, lorsque votre application démarre, le bean de la classe Foo.class n'est pas créé. – StanislavL

+0

Je n'arrive pas à le faire dans ma définition de la classe, mais j'obtiens cette erreur en faisant cela: 'java.lang.IllegalArgumentException: Une erreur est survenue lors du traitement d'un filtre de type ANNOTATION @ComponentScan: class com.companyname.projectname.core.Foo n'est pas assignable à l'interface java.lang.annotation.Annotation' –

0

Il y a 2 réponses possibles selon vos besoins:

1) Vous voulez enregistrer à la fois Foo et FooExtend dans votre Contexte de printemps. Dans ce cas, vous pouvez utiliser l'annotation @Qualifier pour injecter une instance ou d'une autre:

@Autowired 
@Qualifier("fooExtend") 
Foo foo; 

2) Vous ne voulez enregistrer FooExtend dans votre contexte de printemps.

@ComponentScan(value = {'your.package.here'}, excludeFilters = { 
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)) 
} 

Cependant, il est nécessaire que Foo et FooExtend sont dans des emballages différents afin que FooExtend est pas non inclus par le filtre ci-dessus.

+0

La solution 2 serait préférable, mais Foo est dans le contexte printanier de Core, provoquant son chargement –

+0

Cela dépend de la façon dont vous numérisez/enregistrez les beans de votre bibliothèque principale. Si c'est @ComponentScan, vous pouvez l'exclure au moyen de Filter. – MrKiller21

+0

Je n'ai pas réussi à le faire fonctionner. Il m'a donné l'erreur suivante: 'java.lang.IllegalArgumentException: Une erreur s'est produite lors du traitement d'un filtre de type ANNOTATION @ComponentScan: class com.companyname.projectname.core.Foo n'est pas assignable à l'interface java.lang.annotation.Annotation' –