2014-12-23 8 views
13

Mam zależność cykliczną i konfigurację Java. Rozdzielanie go przy pomocy xml config jest bardzo łatwe, nie mogę go rozwiązać za pomocą konfiguracji java bez @Autowired. Fasola:Wiosna. Rozwiązuj zależność cykliczną za pomocą konfiguracji Java i bez @Autowired

public class A { 
    private B b; 

    public B getB() { 
     return b; 
    } 

    public void setB(B b) { 
     this.b = b; 
    } 
} 

public class B { 
    private A a; 

    public A getA() { 
     return a; 
    } 

    public void setA(A a) { 
     this.a = a; 
    } 
} 

próbowałem tego (Czytałem, że z @Bean adnotacji wiosny nie wywoła metodę za każdym razem fasola jest wymieniony, ale w tym przypadku to faktycznie został wywołany przez cały czas):

@Configuration 
public class Config { 
    @Bean 
    public A a() { 
     A a = new A(); 
     a.setB(b()); 
     return a; 
    } 

    @Bean 
    public B b() { 
     B b = new B(); 
     b.setA(a()); 
     return b; 
    } 
} 

A to, ze @Autowired pól klasy konfiguracja:

@Configuration 
public class Config { 
    @Autowired 
    A a; 
    @Autowired 
    B b; 

    @Bean 
    public A a() { 
     A a = new A(); 
     a.setB(b); 
     return a; 
    } 

    @Bean 
    public B b() { 
     B b = new B(); 
     b.setA(a); 
     return b; 
    } 
} 

również próbowałem wszystko powyżej @Lazy adnotacji. Nie pomaga. Ale działa idealnie, gdy przypisuję seterów A i B przy pomocy @Autowired. Ale to nie jest to, czego teraz chcę. Co robię źle i czy istnieje sposób, aby rozwiązać zależność Circular w java config bez użycia @Autowired?

+0

Czy możesz wyjaśnić _Ale nie jest to, co chcę teraz._? Jeśli jest to odpowiednie narzędzie do pracy ... –

+0

@Sotirios Delimanolis moja aplikacja jest teraz trochę nieporządna i obawiam się, że pomylę się z zależnościami w całym kodzie. To nie jest religijne i uwielbiam Autowired, ale w tej chwili wolę koncentrować komponenty w jednym pliku konfiguracyjnym i zarządzać zależnościami za pomocą rąk. Zastanawiam się też, czy to w ogóle możliwe. –

+0

Na wiosennym forum odbyła się interesująca dyskusja: http: //forum.spring.io/forum/spring-projects/container/127799-circular-dependencies-with-autowired-in-java-based-configuration –

Odpowiedz

9

Zachowanie chcesz dostać się następujące

A a = new A(); 
B b = new B(); 
a.setB(b); 
b.setA(a); 

@Bean metody nie daje to. Są one uruchamiane do końca, aby zapewnić wystąpienie komponentu bean.

Zasadniczo musisz częściowo utworzyć jedną z instancji, a następnie zakończyć inicjowanie, gdy utworzysz drugą.

@Configuration 
class Config { 
    @Bean 
    public A a() { 
     A a = new A(); 
     return a; 
    } 

    @Bean 
    public B b() { 
     B b = new B(); 
     A a = a(); 
     b.setA(a); 
     a.setB(b); 
     return b; 
    } 
} 

lub

@Bean 
public B b(A a) { 
    B b = new B(); 
    b.setA(a); 
    a.setB(b); 
    return b; 
} 
+0

Metoda 'b' może również' @ Autowire' bean 'a' (aby uniknąć niejawnego wywołania do metody 'a()'. Czy to nie prawda? – wassgren

+0

@wassgren Absolutnie, chociaż nie potrzebuje wyraźnego '@ Autowired'. –

+0

Ale to będzie oznaczać, że aib będą miały nieodwzorowane odniesienia do siebie nawzajem. – flup

6

Innym sposobem korzystania @Autowired i @Component jest korzystać z tego wzoru:

@Component 
class A { 
    private B b; 

    public B getB() { 
     return b; 
    } 

    public void setB(final B b) { 
     this.b = b; 
    } 
} 


@Component 
class B { 
    private final A a; 

    @Autowired 
    public B(final A a) { 
     this.a = a; 
     a.setB(this); 
    } 

    public A getA() { 
     return a; 
    } 
} 

Eliminuje to konieczność stosowania osobnego @Configuration -class. Ponadto, metoda setB może być chroniona pakietowo, jeśli klasy istnieją w tym samym pakiecie, aby zminimalizować zakres w jak największym stopniu.

+0

Twoja odpowiedź jest również przydatna, to smutne, że nie mogę głosować, ponieważ jestem nowicjuszem, dziękuję –

1

Chcę dodać inne możliwe rozwiązanie dla twojego kodu. Zamiast ustawiać wzajemnie od siebie zależnych prawo w config:

@Configuration 
public class Config { 
    @Bean 
    public A a() { 
     A a = new A(); 
     a.setB(b()); 
     return a; 
    } 

    @Bean 
    public B b() { 
     B b = new B(); 
     b.setA(a()); 
     return b; 
    } 
} 

Można również pozwolić sprężyna do pracy z mocą @Autowired adnotacji.

@Configuration 
public class Config { 
    @Bean 
    public A a() { 
     A a = new A(); 
     return a; 
    } 

    @Bean 
    public B b() { 
     B b = new B(); 
     return b; 
    } 
} 

public class A { 
    private B b; 

    @Autowired 
    public setB(B b) { this.b = b; } 
} 

public class B { 
    private A a; 

    @Autowired 
    public setA(A a) { this.a = a; } 
} 

Oczywiście to nie jest trywialne od „czystej// czytelny zrozumiały” punktu widzenia, ponieważ teraz konfiguracja jest mieszany w @Configuration i klasa sama. Ale ponieważ zależności cykliczne są dość rzadkie, możemy sobie pozwolić na hackowanie.

+0

Chodziło o to, aby to zrobić ** bez ** '@ Autowired' (choć nie pytaj mnie dlaczego –

+0

O, widzę, w każdym razie, niech to będzie tutaj. –

Powiązane problemy