1. Enregistrez la source BeanDefinition
Le conteneur Spring est vide au début. Accédez à diverses sources pour trouver la beanDefinition. Ces sources peuvent être des classes de configuration ou des fichiers XML. Dans la méthode de construction, une source principale sera obtenue, qui est la classe bootstrap, et la beanDefinition sera obtenue en fonction de la classe bootstrap.
2. Déduire le type d'application
Déterminez le type de référence en fonction du package jar
3 Enregistrez l'initialiseur ApplicationContext
Étendez l'ApplicationContext
4 Enregistrez l'auditeur
Écoutez les événements importants
5. la classe de démarrage principale
enregistre la classe principale en cours d'exécution.
1. Obtenez SpringApplicationRunListeners. Le nom n'est pas bon, mais il s'agit en fait d'un éditeur d'événements
publie l'événement de démarrage de l'application. Il publie les événements sur les nœuds importants lorsque le programme démarre
public static void main(String[] args) throws Exception{ // 添加 app 监听器 SpringApplication app = new SpringApplication(); app.addListeners(e -> System.out.println(e.getClass())); // 获取事件发送器实现类名 List<String> names = SpringFactoriesLoader.loadFactoryNames(SpringApplicationRunListener.class, A39_2.class.getClassLoader()); for (String name : names) { System.out.println(name); Class<?> clazz = Class.forName(name); Constructor<?> constructor = clazz.getConstructor(SpringApplication.class, String[].class); SpringApplicationRunListener publisher = (SpringApplicationRunListener) constructor.newInstance(app, args); // 发布事件 DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext(); publisher.starting(bootstrapContext); // spring boot 开始启动 publisher.environmentPrepared(bootstrapContext, new StandardEnvironment()); // 环境信息准备完毕 GenericApplicationContext context = new GenericApplicationContext(); publisher.contextPrepared(context); // 在 spring 容器创建,并调用初始化器之后,发送此事件 publisher.contextLoaded(context); // 所有 bean definition 加载完毕 context.refresh(); publisher.started(context); // spring 容器初始化完成(refresh 方法调用完毕) publisher.running(context); // spring boot 启动完毕 publisher.failed(context, new Exception("出错了")); // spring boot 启动出错 }
2. args
3. Prepare Environment ajoute des paramètres de ligne de commande (*)
public static void main(String[] args) throws IOException { ApplicationEnvironment env = new ApplicationEnvironment(); // 系统环境变量, properties, yaml env.getPropertySources().addLast(new ResourcePropertySource(new ClassPathResource("step3.properties"))); env.getPropertySources().addFirst(new SimpleCommandLinePropertySource(args)); for (PropertySource<?> ps : env.getPropertySources()) { System.out.println(ps); } // System.out.println(env.getProperty("JAVA_HOME")); System.out.println(env.getProperty("server.port")); }
4. Traitement ConfigurationPropertySources (*)
publier les événements préparés par l'environnement d'application
public static void main(String[] args) throws IOException, NoSuchFieldException { ApplicationEnvironment env = new ApplicationEnvironment(); env.getPropertySources().addLast( new ResourcePropertySource("step4", new ClassPathResource("step4.properties")) ); ConfigurationPropertySources.attach(env); for (PropertySource<?> ps : env.getPropertySources()) { System.out.println(ps); } System.out.println(env.getProperty("user.first-name")); System.out.println(env.getProperty("user.middle-name")); System.out.println(env.getProperty("user.last-name")); } }
5. , analysé par StandardConfigDataLocationResolver
spring.application.json
public class Step5 { public static void main(String[] args) { SpringApplication app = new SpringApplication(); app.addListeners(new EnvironmentPostProcessorApplicationListener()); /*List<String> names = SpringFactoriesLoader.loadFactoryNames(EnvironmentPostProcessor.class, Step5.class.getClassLoader()); for (String name : names) { System.out.println(name); }*/ EventPublishingRunListener publisher = new EventPublishingRunListener(app, args); ApplicationEnvironment env = new ApplicationEnvironment(); System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>> 增强前"); for (PropertySource<?> ps : env.getPropertySources()) { System.out.println(ps); } publisher.environmentPrepared(new DefaultBootstrapContext(), env); System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>> 增强后"); for (PropertySource<?> ps : env.getPropertySources()) { System.out.println(ps); } } private static void test1() { SpringApplication app = new SpringApplication(); ApplicationEnvironment env = new ApplicationEnvironment(); System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>> 增强前"); for (PropertySource<?> ps : env.getPropertySources()) { System.out.println(ps); } ConfigDataEnvironmentPostProcessor postProcessor1 = new ConfigDataEnvironmentPostProcessor(new DeferredLogs(), new DefaultBootstrapContext()); postProcessor1.postProcessEnvironment(env, app); System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>> 增强后"); for (PropertySource<?> ps : env.getPropertySources()) { System.out.println(ps); } RandomValuePropertySourceEnvironmentPostProcessor postProcessor2 = new RandomValuePropertySourceEnvironmentPostProcessor(new DeferredLog()); postProcessor2.postProcessEnvironment(env, app); System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>> 增强后"); for (PropertySource<?> ps : env.getPropertySources()) { System.out.println(ps); } System.out.println(env.getProperty("server.port")); System.out.println(env.getProperty("random.int")); System.out.println(env.getProperty("random.int")); System.out.println(env.getProperty("random.int")); System.out.println(env.getProperty("random.uuid")); System.out.println(env.getProperty("random.uuid")); System.out.println(env.getProperty("random.uuid")); } }
6 Liez spring.main à l'objet SpringApplication (*)
Attribuez la valeur dans le fichier de configuration à la valeur d'attribut par défaut de SpringApplication
public class Step6 { // 绑定 spring.main 前缀的 key value 至 SpringApplication, 请通过 debug 查看 public static void main(String[] args) throws IOException { SpringApplication application = new SpringApplication(); ApplicationEnvironment env = new ApplicationEnvironment(); env.getPropertySources().addLast(new ResourcePropertySource("step6", new ClassPathResource("step6.properties"))); System.out.println(application); Binder.get(env).bind("spring.main", Bindable.ofInstance(application)); System.out.println(application); }
7. (*)
public class Step7 { public static void main(String[] args) { ApplicationEnvironment env = new ApplicationEnvironment(); SpringApplicationBannerPrinter printer = new SpringApplicationBannerPrinter( new DefaultResourceLoader(), new SpringBootBanner() ); // 测试文字 banner // env.getPropertySources().addLast(new MapPropertySource("custom", Map.of("spring.banner.location","banner1.txt"))); // 测试图片 banner // env.getPropertySources().addLast(new MapPropertySource("custom", Map.of("spring.banner.image.location","banner2.png"))); // 版本号的获取 System.out.println(SpringBootVersion.getVersion()); printer.print(env, Step7.class, System.out); } }
8. Créer un conteneur
private static GenericApplicationContext createApplicationContext(WebApplicationType type) { GenericApplicationContext context = null; switch (type) { case SERVLET -> context = new AnnotationConfigServletWebServerApplicationContext(); case REACTIVE -> context = new AnnotationConfigReactiveWebServerApplicationContext(); case NONE -> context = new AnnotationConfigApplicationContext(); } return context; }
9. Préparer la version du conteneur
événement initialisé du contexte d'application
10. Charger la définition du bean
publier l'événement préparé pour l'application
DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory(); AnnotatedBeanDefinitionReader reader1 = new AnnotatedBeanDefinitionReader(beanFactory); XmlBeanDefinitionReader reader2 = new XmlBeanDefinitionReader(beanFactory); ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(beanFactory); reader1.register(Config.class); reader2.loadBeanDefinitions(new ClassPathResource("b03.xml")); scanner.scan("com.itheima.a39.sub");
11.
12. Exécuter Le coureur
publie l'événement d'application prête
Il y a une exception et publie l'événement d'application ayant échoué
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!