Circural dependency - jaka jest przyczyna?

0

Pewnie mogę sobie z tym poradzić za pomocą @Lazy lub wstrzykiwaniem przez setery, ale wolałbym to lepiej rozwiązać i poznać przyczynę.

Projekt się buduje (bez testów):
https://gitlab.com/namingexception/training-kafka

ale przy odpaleniu leci:

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

   sendUpperCaseJob (field com.kafkatolowercasespring.core.service.kafka.KafkaMessageSender com.kafkatolowercasespring.core.job.SendUpperCaseJob.kafkaMessageSender)
┌─────┐
|  kafkaMessageSender defined in file [C:\Users\pt\Documents\git2\kafka-tolowercase-spring\kafka-tolowercase-spring-core\target\classes\com\kafkatolowercasespring\core\service\kafka\KafkaMessageSender.class]
↑     ↓
|  kafkaTemplate defined in class path resource [com/kafkatolowercasespring/core/config/KafkaProducerConfig.class]
↑     ↓
|  producerFactory defined in class path resource [com/kafkatolowercasespring/core/config/KafkaProducerConfig.class]
└─────┘

kafkaMessageSender rzeczywiście potrzebuje kafkaTemplate a
kafkaTemplate potrzebuje producerFactory,
ale producerFactory nie potrzebuje kafkaMessageSender.
Czemu spring twierdzi, że potrzebuje?

1

Obstawiam, że problem jest z Map<String, Object>. Jak spróbowałem to wszczepić u siebie to dostałem mapę wszystkich beanów. Pewnie traktuje to jako potencjalnego kandydata. Nie wiem dlaczego to by miało coś psuć, ale spróbuj dodać @Qualifier.

0

Lol, to jest nawet łatwe do odtworzenia!

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class);
    }

    class Fasola {}

    class JasFasola {}

    @Bean
    Fasola getCos(Map<String, Object> mapa) {
        return new Fasola();
    }

    @Bean
    JasFasola getCosInnego(Fasola param) {
        return new JasFasola();
    }

    @Bean
    Map<String, Object> mapa() {
        var a = new HashMap<String, Object>();
        a.put("asd", "asd");
        return a;
    }
}

Nie wiem czy nie warto by było tego zaraportować jako buga.

0

Co ciekawe jak dodam @Qualifier to on nie wstrzykuje wskazanej mapy tylko wtstrzykuje mapę z mapy, której dopiero wartość jest tą mapą :O

0

Tak, wygląda na to, że jak Spring zobaczy kolekcję albo mapę to zaczyna wrzucać wszystkie beany, które pasują. Jeśli któryś z jest w trakcie kreacji to jest problem i ten dziwny błąd. Ten @Qualifier zmienił tu tylko tyle, że zawęził zakres.

Najlepiej buduj sobie tę mapę w producerFactory, bo nie ma za bardzo powodu, żeby to istniało jako bean.

4

Tak, wygląda na to, że jak Spring zobaczy kolekcję albo mapę to zaczyna wrzucać wszystkie beany, które pasują

No tak to generalnie działa - polecam dokumuntację:

You can also instruct Spring to provide all beans of a particular type from the ApplicationContext by adding the @Autowired annotation to a field or method that expects an array of that type, as the following example shows[...]
The same applies for typed collections, as the following example shows:

public class MovieRecommender {

    private Set<MovieCatalog> movieCatalogs;

    @Autowired
    public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {
        this.movieCatalogs = movieCatalogs;
    }

    // ...
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1