webentwicklung-frage-antwort-db.com.de

Wie verwende ich spring @Lookup Annotation?

Ich muss Prototypenklassen von Singleton bekommen. Ich habe festgestellt, dass die Methodeninjektion der Weg ist, aber ich weiß nicht wirklich, wie man die @Lookup-Annotation von spring verwendet.

Ich bin neu bei der Abhängigkeitsinjektion, und ich habe mich für die Annotationskonfiguration entschieden, also möchte ich in dieser Richtung weitermachen.

Ich habe herausgefunden, dass die @Lookup-Anmerkung erst kürzlich hinzugefügt wurde ( https://spring.io/blog/2014/09/04/spring-framework-4-1-ga-is-here ), aber ich kann nicht überall finden, wie man es benutzt.

Hier ist also ein vereinfachtes Beispiel

Konfigurationsklasse:

@Configuration
@Lazy
public class ApplicationConfiguration implements ApplicationConfigurationInterface {

  @Bean
  public MyClass1 myClass1() {
    return new ContentHolderTabPaneController();
  }

  @Bean
  @Scope("prototype")
  public MyClass2 myClass2() {
    return new SidebarQuickMenuController();
  }
}

Und hier ist ein Klassenbeispiel:

public class MyClass1 {
  doSomething() {
    myClass2();
  }

  //I want this method to return MyClass2 prototype
  public MyClass2 myClass2(){
  }
}

Wie mache ich das mit @Lookup Annotation?

12
Miljac

Bevor Sie die @Lookup-Annotation auf Ihre public MyClass2 myClass2()-Methode anwenden, lesen Sie dies in @ Lookup's Javadoc :

der Container generiert Laufzeitunterklassen der Klasse, die die Methode enthält, über CGLIB. Aus diesem Grund können solche Suchmethoden nur für Beans funktionieren, die der Container durch reguläre Konstruktoren instanziiert (dh Lookup-Methoden können bei Beans, die von Factory-Methoden wo zurückgegeben werden, nicht ersetzt werden wir können ihnen keine Unterklasse dynamisch zur Verfügung stellen).

Entfernen Sie also die folgende Factory-Style-Bean-Deklaration aus ApplicationConfiguration:

  @Bean
  public MyClass1 myClass1() {
    return new ContentHolderTabPaneController();
  }

und fügen Sie @Component-Annotation hinzu, damit Spring die Bean instanziieren kann (fügen Sie der Methode auch die @Lookup-Annotation hinzu):

@Component
public class MyClass1 {
  doSomething() {
    myClass2();
  }

  //I want this method to return MyClass2 prototype
  @Lookup
  public MyClass2 myClass2(){
    return null; // This implementation will be overridden by dynamically generated subclass
  }
}

Holen Sie jetzt myClass1 bean aus dem Kontext, und die myClass2-Methode sollte ersetzt/überschrieben werden, um jedes Mal eine neue Prototyp-Bean zu erhalten.


Update:

Verwendung der werkseigenen Methodendeklaration

Es ist nicht schwer, die kommentierte @Lookup-Methode (die "Suchmethode") zu implementieren. Ohne @Lookup und ohne Änderung der Konfigurationsklasse sieht MyClass1 jetzt so aus (Spring generiert tatsächlich eine ähnliche Implementierung in einer Unterklasse, wenn @Lookup verwendet wurde):

public class MyClass1 {
  doSomething() {
    myClass2();
  }

  //I want this method to return MyClass2 prototype
  @Autowired
  private ApplicationContext applicationContext;
  public MyClass2 myClass2() {
      return applicationContext.getBean(MyClass2.class);
  }
}

Spring injiziert den ApplicationContext für Sie.

28
qingbo

Wenn Sie nicht mit Spring 4.1 arbeiten, können Sie stattdessen die Provider-Injektion verwenden:

public class MyClass1 {
  @Autowired
  private Provider<MyClass2> myClass2Provider;

  doSomething() {
    MyClass2 myClass2 = myClass2();
    myClass2.fooBar()
  }

  public MyClass2 myClass2(){
    return myClass2Provider.get();
  }
}

Dies ist DI, IoC, und vermeidet abstrakte Klassen und XML-Definitionen für Suchmethoden.

6
Josh

Sie können myClass2-Bean auch mit TARGET_CLASS proxyMode deklarieren.

  @Bean
  @Scope("prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
  public MyClass2 myClass2() {
    return new SidebarQuickMenuController();
  }
0