CDI: Nutzung von Referenzen

Diskutiere CDI: Nutzung von Referenzen im Application Tier Forum; Hallo zusammen, ich habe folgendes Szenario: Ich habe eine Bean (Session Scoped) A. Diese Bean A erstellt eine Instanz einer Klasse, die...

  1. miketech
    miketech Neues Mitglied
    Hallo zusammen,

    ich habe folgendes Szenario:

    Ich habe eine Bean (Session Scoped) A. Diese Bean A erstellt eine Instanz einer Klasse, die das Interface B implementiert, mittels einer Factory.


    Code (Text):

    @Named
    @RequestScoped
    public class A() {


      public void doSomething() {
         B b = MyFactory.createB();
         b.doSomthingElse();
      }

    }

     
    Nun habe ich das Problem, dass ich von B heraus eigentlich eine Methode aus A aufrufen müsste. Wie gehe ich nun vor? Soll ich die aktuelle Instanz von A als Parameter übergeben? Oder ist das hässlich, wenn ich eigentlich mit CDI arbeite?

    Code (Text):


    @Named
    @RequestScoped
    public class A() {


      public void doSomething() {
         B b = MyFactory.createB(this);
         b.doSomthingElse();
      }

    }

     
    Allerdings erstellt MyFactory ja nur eine Instanz einer Klasse, die B implementiert und von diesen Klassen habe ich ca. 15 verschiedene. Ist es hier dann üblich, dennoch mit bspw. RequestScoped Beans für jede dieser 15 verschiedenen zu arbeiten? Wäre ja durchaus möglich, dass ich dann jeweils eine Instanz mittels CDI zurückliefere.

    Was ist denn hier BestPractice?

    Danke

    Mike
     
  2. Vielleicht hilft dir dieser Kurs hier weiter --> (hier klicken)
  3. TheDoctor
    TheDoctor Neues Mitglied
    Mal andersrum gefragt, wieso injizierst Du A und B nicht?
     
  4. miketech
    miketech Neues Mitglied
    Hi,

    danke für deine Antwort. Mit A mache ich das ja. Aber bei B gibt es zig verschiedene Varianten, wo ich abhängig von verschiedenen Parametern eine andere Variante benötige. Es wäre schon möglich in der Factory zu sagen:

    Code (Text):

    public class MyFactory {
      public static B create() {
        if ....
         return @Inject B1;
        else
         return @Inject B2;
      }
    }

    public class B {
      private @Inject A a;
    }
     
    Weiß nicht, ob das syntaktisch so möglich ist bei dem return. Aber ich habe so etwas meine Bedenken, dass ich den RequestScope nicht immer einhalte. Vielleicht benötige ich zwei verschiedene B1 in einem Request. Ich weiß nicht, ob ich dann nicht aus Versehen auf derselben Instanz arbeite, obwohl ich eigentlich zwei verschiedene bräuchte.

    Gruß

    Mike
     
  5. TheDoctor
    TheDoctor Neues Mitglied
    Zunächst würde ich grundlegend nochmal über die Architektur nachdenken. Statische Factories sind wahnsinnig schlecht mit Blick auf Testbarkeit da sowas quasi nicht weg zu mocken ist.

    Ohne Garantie auf Richtigkeit weil ich selbst kein CDI Pro bin würde ich aber folgendes versuchen. Ich würde mir für alle deine Implementierungen von B entsprechende Qualifier erstellen und dann direkt aus Klasse A die entsprechende Implementierung über Instance injizieren
    Code (Text):


     @Inject @Bimpl1
        private Instance<B> Bimpl1;

        @Inject @Bimpl2
        private Instance<B> Bimpl2;

        @Inject @Bdefault
        private Instance<B> Bdefault;
           
        private B b;

        protected void AMethode() {
            if (Bdefault = true) {
                b = Bdefault.get();
            } else if (!Bimpl1 = true) {
                b = Bimpl1.get();
               ........
            }
     
    Wobei auch Field Injection eigentlich nicht so günstig ist. Ich tendiere immer dazu alles im Konstruktor oder an der Methode wo ich es nutze zu injizieren.

    Um nun von B auf A zugreifen zu können und keine zirkuläre Abhängigkeit zu bekommen würde ich dann entsprechend in B eine lazy Injection machen:

    Code (Text):
    @Inject
        Instance<A> aInstance;

        public A getA()
        {
            return aInstance.get();
        }      
     
  6. FArt
    FArt Neues Mitglied
    Ich würde mich auch mal fragen, warum B eine Methode von A aufrufen muss, also was dieses Konstrukt realisieren soll. Evtl. gibt es da eine bessere Lösung.
     
  7. Landei
    Landei Neues Mitglied
    Wenn es wirklich so schwierig ist, das aktuell "richtige" B herauszufinden, brauchst du einen entsprechenden Dienst dafür, und den kannst du dir dann injizieren lassen.
     
  8. miketech
    miketech Neues Mitglied
    Hallo zusammen,

    danke für Eure Antworten. Ich werde dann tatsächlich noch einmal umdenken. Das ist dann irgendwie noch nicht ideal von der Architektur. Ich werde versuchen, wirklich komplett auf CDI Beans zu setzen, weil dann muss ich diese Referenzen nicht mitschleifen. Das ist nur, weil ich sonst von einer normalen (nicht CDI) Bean nicht mehr auf die CDI Bean zugreifen kann.

    Gruß

    Mike
     
Die Seite wird geladen...

CDI: Nutzung von Referenzen - Ähnliche Themen

Implementierung der Klasse Konto und Nutzung bereits vorhandener Klassen
Implementierung der Klasse Konto und Nutzung bereits vorhandener Klassen im Forum Java Basics - Anfänger-Themen
Webanwendung mit intensiver Nutzung von Dateien
Webanwendung mit intensiver Nutzung von Dateien im Forum Allgemeines EE
Entwickler Fremdsprachennutzung
Entwickler Fremdsprachennutzung im Forum Plauderecke
Mehrfache Benutzung von Methoden einer Klasse
Mehrfache Benutzung von Methoden einer Klasse im Forum AWT, Swing, JavaFX & SWT
Nutzung einer Klasse die das Iterator-Interface implementiert
Nutzung einer Klasse die das Iterator-Interface implementiert im Forum Java Basics - Anfänger-Themen
Thema: CDI: Nutzung von Referenzen