Dieser Artikel fasst den Bohnenlebenszyklus zusammen. Es ist eine ziemlich interne Geschichte. Wir gehen davon aus, dass Sie die folgenden Schlüsselwörter kennen.
Übrigens habe ich die Spring Professional v5.0-Prüfung abgelegt, die neulich von pivotal gesponsert wurde. Dies ist also eine Zusammenfassung dessen, was ich damals gelernt habe.
Der Lebenszyklus einer Bohne ist grob in drei Teile unterteilt.
Hauptsächlich in dieser Phase
halten. Diese Phase ist die komplexeste. Der allgemeine Fluss ist so
Lass uns genauer hinschauen.
Zunächst werden die zum Generieren der Bean erforderlichen Informationen gelesen.
--Java Config mit @ Configuration
Basierend auf den hier gelesenen Informationen wird eine Bean-Definitionsinformationsliste erstellt. (Die Entität ist BeanDefinition ) Karte des Objekts?) Die Bean-Implementierungsklasse, der Bereich, die abhängigen Beans, Felder usw. werden in die Bean-Definitionsinformationsliste geschrieben.
Class | Name | Scope | Depends on | Property | ... |
---|---|---|---|---|---|
com.example.hoge.AImpl | a | Singleton | b | url=${url} | ... |
com.example.fuga.BImpl | b | Prototype | c | age=10 | ... |
com.example.piyo.CImpl | c | Singleton | ... |
Hier werden die Bean-Definitionsinformationen neu geschrieben. Es ist ein Bild, das die im vorherigen Schritt erstellte Bean-Definitionsinformationsliste geändert hat. Hier wird beispielsweise das Einbetten eines Eigenschaftswerts in einen mit "@ Value" deklarierten Platzhalter ausgeführt.
AImpl.java
@Component("a")
public class AImpl implements A {
@Value("${url}")
private String url;
}
application.properties
url=http://www.sample.com
Tatsächlich wird BeanDefinition basierend auf dem durch @ Value
injizierten Eigenschaftswert geändert.
BeanFactoryPostProcessor realisiert das Umschreiben von Bean-Definitionsinformationen. factory / config / BeanFactoryPostProcessor.java).
Die Verarbeitung wird von der Klasse ausgeführt, die die BeanFactoryPostProcessor-Schnittstelle implementiert.
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory);
}
PropertySourcesPlaceholderConfigurer implementiert BeanFactoryPostProcessor für den Prozess des Einbettens von Eigenschaftswerten mit "@ Value" /springframework/context/support/PropertySourcesPlaceholderConfigurer.java) Die Klasse ist verantwortlich. (Siehe den Link für eine detaillierte Verarbeitung) Bei Verwendung von "@ Value" muss übrigens eine Bean definiert werden, die PropertySourcesPlaceholderConfigurer zurückgibt. (Es scheint nicht notwendig zu sein, es explizit zu definieren, wenn es sich um Spring Boot und Spring 4.3 oder höher handelt.) Diese Bean muss in einer statischen Methode definiert werden, da Spring sie ausführt, bevor die Bean erstellt wird.
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
Damit ist die Generierung von Bean-Definitionsinformationen abgeschlossen. Eigentlich wurde die Bohne noch nicht generiert. Ab der nächsten Phase werden Bohnen erzeugt.
Zu diesem Zeitpunkt wird schließlich eine Bean erstellt und DI (Dependency Injection) ausgeführt. DI wird in der folgenden Reihenfolge ausgeführt.
Die Initialisierungsverarbeitung wird nach der Bean-Generierung durchgeführt.
Als ein Merkmal der Verarbeitung, die hier ausgeführt werden kann, kann die Initialisierungsverarbeitung unter Verwendung der generierten Bean durchgeführt werden.
In dieser Phase wird beispielsweise die Verarbeitung der Methode mit "@ PostConstruct" durchgeführt.
In der Methode mit @ PostConstruct
können Sie den Initialisierungsprozess mit dem injizierten Feld schreiben.
@Component
public class HogeServiceImpl implements HogeService {
private final Fuga fuga;
@Autowired
public HogeServiceImpl(Fuga fuga) {
this.fuga = fuga;
}
//Wird aufgerufen, nachdem DI beendet ist
//Der Rückgabewert muss ungültig sein, kein Argument
@PostConstruct
public void populateCache() {
...
}
}
Vor- und Nachbearbeitung können vor und nach der Initialisierungsverarbeitung dieses Schritts eingefügt werden. Dieser Prozess ist BeanPostProcessor ) Die Klasse, die die Schnittstelle implementiert, macht es.
public interface BeanPostProcessor {
//Vorverarbeitung
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
//Nachbearbeitung
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
Dies ist die Phase, in der die Bohne tatsächlich verwendet wird.
ApplicationContext context = SpringApplication.run(AppConfig.class);
HogeService service = context.getBean("hogeService", HogeService.class); //Holen Sie sich Bean
service.do(); //Verwendung von Bohnen
Dies ist die Phase, in der der DI-Container zerstört wird.
Die Verarbeitung erfolgt vor der Zerstörung des DI-Containers. Methoden mit "@ PreDestroy" werden in dieser Phase verarbeitet.
@Component
public class HogeServiceImpl implements HogeService {
//Wird aufgerufen, bevor der DI-Container zerstört wird
//Der Rückgabewert muss ungültig sein, kein Argument
@PreDestroy
public void clearCache() {
...
}
}
Wenn die Methode close von ConfigurableApplicationContext aufgerufen wird Der DI-Container wird zerstört.
context.close();
Wenn es von "SpringApplication.run ()" generiert wird, wird es mit dem Herunterfahren der JVM verbunden und der DI-Container wird zerstört.
ConfigurableApplicationContext context = SpringApplication.run(AppConfig.class);
//ShutdownHook ist in der JVM registriert