Considérez le morceau de code suivant

public interface Iface1 { }
public interface Iface2 { }

public class A implements Iface1, Iface2 {

}

@Configuration
public class AutoConfig {

  @Bean
  Iface1 provideIface1Impl() {
      return new A();  // instance no 1234
  }

  @Bean
  @ConditionalOnBean(A.class)
  @Autowired
  Iface2 provideIface2Impl(A aImpl) {
    return aImpl;
  }
}

Je voudrais que la deuxième méthode @Bean soit automatiquement câblée avec l'instance de la première (1234) et j'aimerais que la deuxième méthode @Bean renvoie la même instance, afin que je puisse utiliser la même instance pour les clients de Iface1 et Iface2.

Le problème actuel est que spring ne lance pas le second @Bean car il n'y a pas de @Bean de type A.class - le bean créé est considéré comme Iface1 même s'il est de type A.

0
LIvanov 28 nov. 2017 à 13:12

3 réponses

Meilleure réponse

Définissez simplement le bean A. Lors de l'injection de IFace1 et Iface2, ils seront automatiquement résolus en A (si A est la seule implémentation bien sûr).

@Bean
public A a() {
    return new A();
}
2
Gorazd Rebolj 28 nov. 2017 à 10:23

En plus de ce que d'autres ont répondu, j'aimerais couvrir cette partie de la question qui touche les dépendances de bean. Pour injecter une dépendance dans une méthode annotée @Bean, il existe deux façons:

Exemples des deux:

@Configuration
public class AppConfig {

    @Bean
    public Foo foo() {
        return new Foo();
    }

    @Bean
    public Bar bar() {
        return new Bar(foo());
    }

    @Bean
    public Baz baz(Foo foo) {
        return new Baz(foo);
    }
}

Ainsi, votre provideIface2Impl pourrait ressembler à ceci:

@Bean
Iface2 provideIface2Impl(A aImpl) {
    return aImpl;
}

// or...

@Bean
Iface2 provideIface2Impl() {
    return (Iface2)provideIface1Impl();
}

Mais ne l'utilisez pas de cette façon , cela entraînera des bogues subtils comme le double proxy ou l'erreur "Aucun bean unique de type", etc. Préférez ce que Gorazd suggéré.

0
Yoory N. 28 nov. 2017 à 12:58

Je pense que vous devriez essayer d'en définir un seul @Bean. Cela créera un singleton:

@Bean
public A a() {
      return new A();
}

Ensuite, utilisez simplement le nom de ce bean dans l'annotation @Qualifier:

@Autowired
@Qualifier("a")
private Iface1 iface1;

@Autowired
@Qualifier("a")
private Iface2 iface2;
0
Mykola Yashchenko 28 nov. 2017 à 10:20
47528922