2016-11-17 3 views
2

Der folgende Code funktioniert gut in Frühling 4, aber ich frage mich, warum die getBean (FooService.class) eine bereits geladene Bean zurückgibt. Ich dachte, dass die Reihenfolge des Bean-Ladens nicht garantiert ist, was bedeutet, dass es möglich ist, eine Null-Bean zu erhalten. Liegt es daran, dass das Ladeziel eine Klasse ist, keine String (dh Objekt), oder liegt es daran, dass die FooService-Bean einen speziellen Bereich hat, wie Prototyp? Wenn ja, was ist der Unterschied zwischen getBean (Klasse) und getBean (Objekt)Warum diese Bean nicht null ist

public abstract class AbstractService implements ApplicationContextAware { 
    protected ApplicationContext applicationContext; 

    protected FooService fooService; 

    @Override 
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
     this.applicationContext = applicationContext; 
    } 

    @PostConstruct 
    protected void postConstruct() { 
     fooService = applicationContext.getBean(FooServiceImpl.class); 
    } 
+0

Ich denke, das ist der Sinn des Frühlings, um keine Nullobjekte zu erhalten – XtremeBaumer

+0

Eigentlich denke ich, Ihre * Bean * ist ** null **, ich meine, Sie verwenden die * ApplicationContext *, um die spezifische Bean-Objekt zu laden. Mit Frühling brauchst du es nicht. Sie können die Annotation * @ Autowired * für den Bean-Parameter oder besser in einem Klassenkonstruktor, in dem die Bean ein Parameter ist, oder in einer * set * -Methode verwenden. –

Antwort

0

Für den Anfang String ist eine volle Recht Klasse, wie die Sie selbst erstellen können.

Der Grund, warum Sie etwas in fooService erhalten, ist, dass der ApplicationContext getBean method in der Lage ist, eine verwaltete Bean gemäß dem Argument, das Sie übergeben, abzurufen.

Wenn es nicht möglich wäre, die Bohne abzurufen, können Sie einige dieser Ausnahmen erhalten:

Wirft: NoSuchBeanDefinitionException - wenn keine Bohne des angegebenen Typs NoUniqueBeanDefinitionException gefunden wurde - wenn mehr als eine Bohne von wurde die gegebene Art BeansException gefunden - wenn die Bohne nicht die Bohne des angegebenen Typs

+0

, aber was ist, wenn eine Bean nicht initialisiert wurde, dh nicht in den Kontext geladen wurde und diese Bean früher als die FooService-Bean initialisiert wurde. Auf diese Weise würde getBean null zurückgeben. – Tiina

+0

Siehe meine Bearbeitung bitte. – Andres

+0

ist es wahr, dass applicationContext.getBean (...) genau wie (at) Autowired ist, würde dieser Frühling sicherstellen, dass eine Bean zurückgegeben wird, wenn sie ihre Definition finden könnte? – Tiina

1

ApplicationContext::getBean Methode erstellt werden könnte erzeugt, wenn es bereits erstellt worden ist.

für die folgenden zwei Bean-Klassen:

@Component 
public class Bean1 { 

    @Autowired 
    private ApplicationContext applicationContext; 

    public Bean1() { 
     System.out.println("Bean 1 constructor"); 
    } 

    @PostConstruct 
    public void init() { 
     System.out.println("Bean 1 @PostConstruct started"); 
     applicationContext.getBean(Bean2.class); 
     System.out.println("Bean 1 @PostConstruct completed"); 
    } 
} 

@Component 
public class Bean2 { 

    @Autowired 
    private ApplicationContext applicationContext; 

    public Bean2() { 
     System.out.println("Bean 2 constructor"); 
    } 

    @PostConstruct 
    public void init() { 
     System.out.println("Bean 2 @PostConstruct started"); 
     applicationContext.getBean(Bean1.class); 
     System.out.println("Bean 2 @PostConstruct completed"); 
    } 
} 

die gedruckte Ausgabe im Kontext der Initialisierung ist:

Bean 1 constructor 
Bean 1 @PostConstruct started 
Bean 2 constructor 
Bean 2 @PostConstruct started 
Bean 2 @PostConstruct completed 
Bean 1 @PostConstruct completed 

Wie für verschiedene getBean Methoden, wenn Sie in einer Klasse übergeben, dann genau eine Bohne dieser Klasse muss im Anwendungskontext vorhanden sein (andernfalls würde Spring nicht die von mehreren Bean-Instanzen dieser Klasse anfordern), während die Suche nach Namen Ihnen erlaubt, eine bestimmte benannte Bean-Instanz zu erhalten.

+0

könnten Sie ein offizielles Dokument finden, das "@PostConstruct-Methode unterstützt, die aufgerufen wird, nachdem alle Beans erstellt wurden." Aufgrund seiner Kommentare wird postConstruct unmittelbar nach dem Erstellen dieser Bean aufgerufen. Und ich denke, jede Bohne wird nacheinander gebaut. Also ein bisschen mehr Beweise bitte :) – Tiina

+0

@Tiina Sie scheinen richtig zu sein, es gibt keine Garantie, dass Bohnen, die nicht autowired sind, explizit an dieser Stelle erstellt wurden. Ich habe meine Antwort bearbeitet. –

+0

@Dragon Bozanovic sehr klar. :) – Tiina