Cycle de vie du conteneur à ressort
La ConfigurableApplicationContext.refresh()
méthode d' exécution est le point d'entrée principal pour le début du cycle de vie du conteneur Spring. L'appel BeanDefinitionRegistryPostProcessor
et les BeanFactoryPostProcessor
deux post-traitements sont les étapes les plus importantes, car la méthode d' ConfigurationClassPostProcessor
exécution est déclenchée pour réaliser l'analyse du fichier de classe dans le package spécifié sous le chemin de classe .postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
Comprendre BeanDefinition
BeanDefinition
Est une interface utilisée pour décrire les informations Bean, telles que les attributs, les paramètres du constructeur, la portée du bean, le chargement différé, etc. Lors de l'appel pour applicationContext.getBean(…)
obtenir l'objet d'instance Bean, si le Bean n'a pas été créé, le Bean sera créé via BeanDefinition
les informations de description dans BeanDefinition. BeanDefinition possède les classes d'implémentation importantes suivantes.
AnnotatedGenericBeanDefinition
L'encapsulation est utilisée dans la classe de démarrage .- Les classes analysées sous l'analyse du package classpath sont utilisées :, vous pouvez le voir
ScannedGenericBeanDefinition
à laClassPathScanningCandidateComponentProvider
ligne 418. - Utilisé par les haricots importés
AnnotatedGenericBeanDefinition
.
Par exemple: laspring.factories
classe configurée est le bean importé par la classe de démarrage, et la classe de configuration interne non statiqueorg.springframework.context.annotation.ConfigurationClassBeanDefinitionReader
peut être vue au point d' arrêt sur la ligne 137 - Par
@Bean
méthode de configuration utilisant le beanConfigurationClassBeanDefinition
Lorsque vous appelezapplicationContext.getBean()
getting Bean, si vous n'avez pas encore créé l'objet bean,AbstractBeanFactory.getMergedLocalBeanDefinition()
les différents types seBeanDefinition
transforment enRootBeanDefinition
Connaître BeanFactoryPostProcessor
Les plants de haricots traduits dans le processeur chinois, les développeurs peuvent implémenter cette interface, la méthode d'interface dans laquelle postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
en beanFactory
modifiant les propriétés BeanDefinition existantes , peut également être utilisée pour ajouter manuellement une personnalisation BeanDefinition
.
BeanDefinitionRegistryPostProcessor
Oui BeanFactoryPostProcessor
, la sous-classe a ajouté des postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
méthodes et les fonctions des deux méthodes d'interface sont fondamentalement les mêmes.
Mais les postProcessBeanDefinitionRegistry(…)
méthodes de la sous-classe sont postProcessBeanFactory(…)
exécutées avant les méthodes de la classe parent .
2.1 Appelez la méthode prepareRefresh () pour activer le conteneur
Cette méthode est appelée uniquement pour définir AbstractApplicationContext
la AtomicBoolean active
valeur de la variable membre dans sur true, ce qui signifie que le conteneur Spring est activé et que la applicationContext.getBean(…)
méthode peut être appelée. Les appels avant cela lèveront une exception « n'a pas encore été actualisé ».
2.2 Configurer les composants nécessaires requis par l'objet ConfigurableListableBeanFactory
prepareBeanFactory(ConfigurableListableBeanFactory beanFactory)
Cette méthode est principalement utilisée pour ajouter certains composants d'initialisation nécessaires à beanFactory:
- Ajouter à
SpringEL表达式解析器
- Ajoutez un
ApplicationContextAwareProcessor
post-processeur, qui est utilisé pour détecter s'il est implémenté lors de l'instanciation du BeanAware方法
et pour réaliser l'injection. - Ajoutez un
ApplicationListenerDetector
post-processeur pour détecter si le bean est implémentéApplicationListener
, et si tel est le cas, ajoutez-le àAbstractApplicationContext
l'ensemble des écouteurs.
2.3 Appelez BeanFactoryPostProcessor pour réaliser l'analyse des paquets
-
Récupérez
AbstractApplicationContext
les variables membresbeanFactoryPostProcessors
enregistrées dans leBeanFactoryPostProcessor
parcours pour appeler laBeanDefinitionRegistryPostProcessor
classe d'implémentation d'interface. Pour le moment, il n'y a que troisBeanFactoryPostProcessor
classes d'implémentation, mais seules les deux premières implémentent l'BeanDefinitionRegistryPostProcessor
interface.
A. CachingMetadataReaderFactoryPostProcessor
RegistreSharedMetadataReaderFactoryBean
plante du haricot, qui atteint la classe d'interface FactoryBean est principalement utilisé lors de la lecture du chemin de la numérisation de documents sous les informations de classe de catégorie, classe liée à:SimpleMetadataReader
,ClassPathScanningCandidateComponentProvider
B. ConfigurationWarningsPostProcessor
Il est utilisé pour vérifier le package d'analyse défini sur la classe de démarrage. Le package d'analyse défini par l'utilisateur ne peut pas être:org.springframework
etorg
, sinon une exception sera levée.C. PropertySourceOrderingPostProcessor
PropertySourceOrderingPostProcessor
Uniquement réaliséBeanFactoryPostProcessor
, le but est de mettreConfigurableEnvironment
le nom "defaultProperties
"PropertySource
à la fin de la collection -
En
beanFactory.getBeanNamesForType(…)
obtenant laBeanDefinitionRegistryPostProcessor
collection de noms de classe qui implémentent l' interface dans le conteneur Spring et en la parcourant, si le bean est égalementPriorityOrdered
la classe d'implémentation de l' interface, engetBean()
obtenant l'objet d'instance, il n'y en a qu'un dans le conteneur à ce momentConfigurationClassPostProcessor
, ce qui est principalement utilisé pour l'analyse de fichiers sous le chemin de classe . -
Appelez la méthode
ConfigurationClassPostProcessor
implémentéepostProcessBeanDefinitionRegistry()
pour démarrer l'analyse du chemin de classe . EnSimpleMetadataReader
spécifiant le fichier de classe sous le package, si la classe analysée est une classe de configuration, ou@Import
la classe importée via des annotations, il continuera à déterminer s'il s'agit d'une classe de configuration de manière récursive, jusqu'à ce qu'elle soit analysée en un Bean ordinaire, puis passéthis.reader.loadBeanDefinitions(configClasses)
et filtré pour répondre aux exigences des commentaires conditionnelsBeanDefinition
-
Parce qu'une fois l'analyse du chemin de classe effectuée, il peut y avoir des beans qui implémentent
BeanDefinitionRegistryPostProcessor
etBeanFactoryPostProcessor
interfèrent, vous devez doncbeanFactory.getBeanNamesForType(…)
récupérer laBeanDefinitionRegistryPostProcessor
collection de noms de classe qui implémentent l' interface dans Spring , supprimer les classes d'implémentationConfigurationClassPostProcessor
qui ont été appelées et parcourir les noms de bean pour obtenirOrdered
les instances qui implémentent l' interface. Après le tri Méthode d'interface de rappel -
Dans while (réitérer), parcourez
BeanDefinitionRegistryPostProcessor
les beans qui n'implémentent pas l'interface de tri .Pourquoi utiliser l'instruction while ? Pour éviter d'injecter une nouvelle
BeanDefinitionRegistryPostProcessor
classe d'implémentation dans la méthode de rappel . Cela peut appeler le nouveauBeanDefinitionRegistryPostProcessor
-
Méthode de
BeanDefinitionRegistryPostProcessor
superclasse de rappel sans triBeanFactoryPostProcessor
postProcessBeanFactory(beanFactory)
-
Obtenez la
BeanFactoryPostProcessor
classe d'implémentation de l' interface, triez et triez en fonction du type d'interface de tri et rappelez la méthode d'interface- Traverser l'exécution pour réaliser le
org.springframework.core.PriorityOrdered
triBeanFactoryPostProcessor
- Traverser l'exécution pour réaliser le
org.springframework.core.Ordered
triBeanFactoryPostProcessor
- L'exécution de la traversée n'implémente pas l'interface de tri
BeanFactoryPostProcessor
- Traverser l'exécution pour réaliser le
2.4 Enregistrer les BeanPostProcessors pour le traitement des beans
-
En
beanFactory.getBeanNamesForType(…)
obtenantBeanPostProcessor
la collection beanName du type -
Traverse beanNames , catégoriser et trier en fonction du type d'interface de tri. Si elle est une
MergedBeanDefinitionPostProcessor
classe de mise en œuvre, il sera également stocké séparément dans une collection. Cette interface est utilisée principalement pour l' usage interne du printemps. Enfin, les trois collections suivantes sont obtenues, parabstractBeanFactory.addBeanPostProcessor(postProcessor)
économieBeanPostProcessor
-
Add
ApplicationListenerDetector
, utilisé pour collecter la classe d'implémentation de l'écouteur d'événements et l'ajouter à laAbstractApplicationContext的applicationListeners
collectionPrécautions: enregistré
BeanPostProcessor
, l'appel seragetBean(beanName)
obtenuBeanPostProcessor实例对象
, etgetBean()
la méthode interne appellera leBeanPostProcessor
processus Bean nouvellement créé existant , de sorte que le premier enregistréBeanPostProcessor
après le processus d'enregistrement peut êtreBeanPostProcessor
, par exemple:
implémenterPriorityOrdered
l'interfaceBeanPostProcessor
après le processus d'enregistrement pour réaliserOrdered
laBeanPostProcessor
réalisation deOrdered
l'interface leBeanPostProcessor
sera enregistré après le traitement n'a pas atteint l'interface de triBeanPostProcessor
2.5 Enregistrer le diffuseur d'événements dans le conteneur Spring
initApplicationEventMulticaster()
La méthode beanFactory.registerSingleton()
est utilisée pour diffuser des événements en enregistrant un diffuseur d'événements avec le conteneur Spring
2.6 Enregistrer l'écouteur d'événements
Utilisé pour charger l'écouteur configuré par le développeur via des annotations, et ne peut écouter que ContextRefreshedEvent
les événements suivants
2.7 Terminer l'instanciation de tous les Beans chargés non paresseux
finishBeanFactoryInitialization(beanFactory);
Obtenez principalement tous les beanNames , parcourez la AbstractBeanFactory.getBean(name)
méthode pour terminer la création du bean. Une fois tous les beans instanciés, repassez l'instance du bean, trouvez SmartInitializingSingleton
les beans qui implémentent l' interface et rappelez les méthodes d'interface.
2.8 Post événement ContextRefreshedEvent
ContextRefreshedEvent
Événements ApplicationStartedEvent
et ApplicationReadyEvent
publication avant l'événement.