Frage

Wenn Sie um mit Spring Auto-Proxy Sachen beginnen verwirren, Sie oft in dieses Verhalten führen, wie dokumentiert:

  

Klassen, die die Umsetzung   BeanPostProcessor Schnittstelle sind   Besonderes, und so behandelt sie   anders durch den Behälter. Alle   BeanPostProcessors und ihre direkt   referenzierten Bohnen werden instanziiert   beim Start, als Teil des Sonder   Anlaufphase des   Application, dann alle,   BeanPostProcessors werden registriert   in einer sortierten Art und Weise - und auf   alle weiteren Bohnen. da AOP   Auto-Proxying wird als umgesetzt   BeanPostProcessor selbst, nein   BeanPostProcessors oder direkt   referenzierten Bohnen sind für   Auto-Proxying (und wird somit nicht haben   Aspekte 'gewebt' in sie.

     

Für eine solche Bohne, sollten Sie eine sehen   info Protokollmeldung: „Bean‚foo‘ist nicht   Anspruch auf die von allen verarbeitet zu werden   BeanPostProcessors (zum Beispiel: nicht   fähigen Auto-Proxying)“.

Mit anderen Worten, wenn ich meine eigene BeanPostProcessor schreiben, und diese Klasse verweist direkt andere Bohnen im Zusammenhang, dann die referenzierten Bohnen nicht für Auto-Proxying berechtigt sein, und eine Nachricht in diesem Sinne Urteil angemeldet ist.

Mein Problem ist, dass das Aufspüren von wo der direkten Bezug wird sehr schwierig sein kann, da die „direkte Referenz“ kann in der Tat eine Kette von transitiven Abhängigkeiten, die in der Hälfte der Bohnen in dem Anwendungskontext Aufnahme endet. Alle Frühling gibt Sie, dass einzelne Info-Nachricht ist, und es ist nicht wirklich viel helfen, über Ihnen zu sagen, wenn eine Bohne hat in diesem Netz von Bezügen gefangen.

Die BeanPostProcessor Ich entwickle hat direkte Verweise auf andere Bohnen, aber es ist eine sehr begrenzte Anzahl von Referenzen. Trotzdem, so ziemlich jede Bohne in meinem Kontext wird dann davon, dass Auto-proxied ausgeschlossen wird, nach den Log-Meldungen, aber ich kann nicht sehen, wo diese Abhängigkeit geschieht.

Hat jemand einen besseren Weg der Verfolgung dieses gefunden down?

War es hilfreich?

Lösung 2

Nur einige Schließung auf diese Frage zu bringen, wurde der Zusammenbruch des nicht initialisierten Objektgraphen durch die BeanPostProcessor verursacht @Autowired mit seinen Abhängigkeiten zu bekommen, und der autowire Mechanismus verursachte effektiv jede andere Bohne Definition initialisiert werden, bevor mein BeanPostProcessor eine Chance ein Mitspracherecht in der Sache zu haben. Die Lösung wird nicht autowiring für Ihre BPPs zu verwenden.

Andere Tipps

Folgen Sie dieses Rezept:

  1. Öffnen BeanPostProcessorChecker in Ihrem IDE (es ist eine innere Klasse von AbstractApplicationContext)
  2. einen Haltepunkt auf if (logger.isInfoEnabled()) { im Verfahren postProcessAfterInitialization Set
  3. Führen Sie den Code
  4. Wenn Sie den Haltepunkt erreicht, sucht Anrufe in Ihrem Stack-Trace getBean(String,Class<T>).

    Einer dieser Anrufe werden versuchen, eine BeanPostProcessor zu erstellen. Das Bohne sollte die Ursache sein.

Hintergrund

Stellen Sie sich diese Situation:

public class FooPP implements BeanPostProcessor {
    @Autowire
    private Config config;
}

Wenn der Frühling config zu erstellen hat (da es eine Abhängigkeit von FooPP ist), hat es ein Problem: Der Vertrag besagt, dass alle BeanPostProcessor auf jede Bohne angewandt werden müssen, die erstellt wird. Aber wenn der Frühling config braucht, gibt es mindestens eine PP (nämlich FooPP), die für den Dienst nicht bereit ist!

Dies wird noch schlimmer, wenn Sie eine @Configuration Klasse verwenden diese Bean zu definieren:

@Configuration
public class BadSpringConfig {
     @Lazy @Bean public Config config() { return new Config(); }
     @Lazy @Bean public FooPP fooPP() { return new FooPP(); }
}

Jede Konfigurationsklasse ist eine Bohne. Das bedeutet eine BeanFactory von BadSpringConfig zu bauen, braucht Frühling den Postprozessor fooPP anzuwenden, sondern um das zu tun, muss er zunächst die BeanFactory ...

In diesem Beispiel ist es möglich, eine der zyklischen Abhängigkeiten zu brechen. Sie können FooPP implementieren BeanFactoryAware machen zu bekommen Frühling die BeanFactory in den Postprozessor injizieren. Auf diese Weise, die Sie nicht autowiring benötigen.

Später im Code können Sie träge für die Bean fragen:

private LazyInit<Config> helper = new LazyInit<Config>() {

    @Override
    protected InjectionHelper computeValue() {
        return beanFactory.getBean( Config.class );
    }
};

@Override
public Object postProcessBeforeInitialization( Object bean, String beanName ) throws BeansException {
     String value = helper.get().getConfig(...);
}

( Quelle für LazyInit )

Um den Kreislauf zwischen der BeanFactory brechen und dem Postprozessor, müssen Sie den Postprozessor in einer XML-Konfigurationsdatei konfigurieren. Frühling kann man erkennen, lesen und baut alle Strukturen ohne verwirrt zu werden.

Nicht sicher, ob es eine Hilfe ist, aber die Eclipse- Frühling IDE 's Graph Ansicht sieht aus wie es bean Referenzen in Aussortieren hilfreich sein könnte ..

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top