事件发布与监听
SpringApplication springApplication = new SpringApplication();
springApplication.addListeners(event -> {
System.out.println("事件来源: " + event.getClass());
});
List<String> appRunListenerNames = SpringFactoriesLoader.loadFactoryNames(SpringApplicationRunListener.class, Step01.class.getClassLoader());
for (String appRunListenerName : appRunListenerNames) {
System.out.println("publisherClass: =>" + appRunListenerName);
Class<?> appRunListenerClazz = Class.forName(appRunListenerName);
Constructor<?> constructor = appRunListenerClazz.getConstructor(SpringApplication.class, String[].class);
SpringApplicationRunListener publisher = (SpringApplicationRunListener) constructor.newInstance(springApplication, args);
DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
publisher.starting(bootstrapContext);
publisher.environmentPrepared(bootstrapContext, new StandardEnvironment());
GenericApplicationContext genericApplicationContext = new GenericApplicationContext();
publisher.contextPrepared(genericApplicationContext);
publisher.contextLoaded(genericApplicationContext);
genericApplicationContext.refresh();
publisher.started(genericApplicationContext, Duration.ofSeconds(10));
publisher.ready(genericApplicationContext, Duration.ofSeconds(11));
publisher.failed(genericApplicationContext, new Exception("故意抛出的异常"));
}
准备Bean
static class Bean4 {
}
static class Bean5 {
}
static class Bean6 {
}
@Configuration
static class Config {
@Bean
public Bean5 bean5() {
return new Bean5();
}
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
return new TomcatServletWebServerFactory();
}
@Bean
public CommandLineRunner commandLineRunner() {
return new CommandLineRunner() {
@Override
public void run(String... args) throws Exception {
System.out.println("\tCommandLineRunner..." + Arrays.toString(args));
}
};
}
@Bean
public ApplicationRunner applicationRunner() {
return new ApplicationRunner() {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("\tApplicationRunner..." + Arrays.toString(args.getSourceArgs()));
System.out.println("\tNonOptionArgs:" + args.getNonOptionArgs());
System.out.println("\tOptionNames:" + args.getOptionNames());
System.out.println("\tOptionArg:server.port: " + args.getOptionValues("server.port"));
}
};
}
}
@Component
public class Bean10 {
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bean4" class="com.you.meet.nice.test.web.springboot.Step02.Bean4"/>
</beans>
new SpringApplication
SpringApplication springApplication = new SpringApplication();
springApplication.addInitializers((applicationContext) -> {
System.out.println("\t执行初始化器回调增强容器");
});
创建容器
private static GenericApplicationContext createApplicationContext(WebApplicationType webApplicationType) {
GenericApplicationContext applicationContext = null;
switch (webApplicationType) {
case SERVLET:
applicationContext = new AnnotationConfigServletWebServerApplicationContext();
break;
case REACTIVE:
applicationContext = new AnnotationConfigReactiveWebServerApplicationContext();
break;
case NONE:
applicationContext = new AnnotationConfigApplicationContext();
break;
default:
break;
}
return applicationContext;
}
准备容器
System.out.println("8. 创建容器");
GenericApplicationContext applicationContext = createApplicationContext(WebApplicationType.SERVLET);
System.out.println("9. 准备容器");
for (ApplicationContextInitializer initializer : springApplication.getInitializers()) {
initializer.initialize(applicationContext);
}
加载BeanDefinition
System.out.println("10. 加载BeanDefinition");
DefaultListableBeanFactory beanFactory = applicationContext.getDefaultListableBeanFactory();
AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(beanFactory);
annotatedBeanDefinitionReader.registerBean(Config.class);
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
xmlBeanDefinitionReader.loadBeanDefinitions(new ClassPathResource("b02.xml"));
ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanFactory);
classPathBeanDefinitionScanner.scan("com.you.meet.nice.test.web.springboot.sub");
refresh
System.out.println("11. refresh容器");
applicationContext.refresh();
执行runner
System.out.println("12. 执行runner");
for (CommandLineRunner commandLineRunner : applicationContext.getBeansOfType(CommandLineRunner.class).values()) {
commandLineRunner.run(args);
}
DefaultApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
for (ApplicationRunner applicationRunner : applicationContext.getBeansOfType(ApplicationRunner.class).values()) {
applicationRunner.run(applicationArguments);
}
for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
System.out.println("beanName:" + beanDefinitionName + " 来源=>" + applicationContext.getBeanFactory().getBeanDefinition(beanDefinitionName).getResourceDescription());
}
applicationContext.close();
环境
- StandardEnvironment是spring中标准的环境类
- ApplicationEnvironment是springboot中的,但是它是default修饰的,所以必须在同一个包下测试,这里建了个org.springframework.boot包
- systemProperties: VM OPTIONS -DJAVA_HOME=abc
- systemEnvironment 系统环境配置
准备step03.properties
user.first-name=zhou
user.middleName=jun
user.lase_name=lin
自定义添加配置来源
ApplicationEnvironment applicationEnvironment = new ApplicationEnvironment();
applicationEnvironment.getPropertySources().addLast(new ResourcePropertySource(new ClassPathResource("application.properties")));
applicationEnvironment.getPropertySources().addLast(new ResourcePropertySource(new ClassPathResource("step03.properties")));
ConfigurationPropertySources.attach(applicationEnvironment);
for (PropertySource<?> propertySource : applicationEnvironment.getPropertySources()) {
System.out.println(propertySource);
}
System.out.println(applicationEnvironment.getProperty("JAVA_HOME"));
System.out.println(applicationEnvironment.getProperty("server.port"));
System.out.println(applicationEnvironment.getProperty("user.first-name"));
System.out.println(applicationEnvironment.getProperty("user.middle-name"));
System.out.println(applicationEnvironment.getProperty("user.lase-name"));
配置文件与随机数加载到环境后置处理器
SpringApplication springApplication = new SpringApplication();
ApplicationEnvironment applicationEnvironment = new ApplicationEnvironment();
System.out.println("=======>增强前");
for (PropertySource<?> propertySource : applicationEnvironment.getPropertySources()) {
System.out.println(propertySource);
}
ConfigDataEnvironmentPostProcessor configDataEnvironmentPostProcessor = new ConfigDataEnvironmentPostProcessor(new DeferredLogs(), new DefaultBootstrapContext(), null);
configDataEnvironmentPostProcessor.postProcessEnvironment(applicationEnvironment, springApplication);
RandomValuePropertySourceEnvironmentPostProcessor randomValuePropertySourceEnvironmentPostProcessor = new RandomValuePropertySourceEnvironmentPostProcessor(new DeferredLog());
randomValuePropertySourceEnvironmentPostProcessor.postProcessEnvironment(applicationEnvironment, springApplication);
System.out.println("=======>增强后");
for (PropertySource<?> propertySource : applicationEnvironment.getPropertySources()) {
System.out.println(propertySource);
}
System.out.println(applicationEnvironment.getProperty("JAVA_HOME"));
System.out.println(applicationEnvironment.getProperty("server.port"));
监听器的方式增强环境
SpringApplication springApplication = new SpringApplication();
springApplication.addListeners(new EnvironmentPostProcessorApplicationListener());
ApplicationEnvironment applicationEnvironment = new ApplicationEnvironment();
System.out.println("=======>增强前");
for (PropertySource<?> propertySource : applicationEnvironment.getPropertySources()) {
System.out.println(propertySource);
}
EventPublishingRunListener publisher = new EventPublishingRunListener(springApplication, args);
publisher.environmentPrepared(new DefaultBootstrapContext(), applicationEnvironment);
System.out.println("=======>增强后");
for (PropertySource<?> propertySource : applicationEnvironment.getPropertySources()) {
System.out.println(propertySource);
}
配置绑定
准备对象
@Data
static class User {
private String firstName;
private String middleName;
private String lastName;
}
准备application.properties
spring.main.lazy-initialization=true
spring.main.banner-mode=off
绑定新对象
ApplicationEnvironment applicationEnvironment = new ApplicationEnvironment();
applicationEnvironment.getPropertySources().addLast(new ResourcePropertySource(new ClassPathResource("application.properties")));
applicationEnvironment.getPropertySources().addLast(new ResourcePropertySource(new ClassPathResource("step03.properties")));
User user = Binder.get(applicationEnvironment).bind("user", User.class).get();
System.out.println(user);
绑定已存在的对象
User user = new User();
user.setFirstName("zzzz");
Binder.get(applicationEnvironment).bind("user", Bindable.ofInstance(user));
System.out.println(user);
绑定SpringApplication
SpringApplication springApplication = new SpringApplication();
System.out.println(springApplication);
Binder.get(applicationEnvironment).bind("spring.main", Bindable.ofInstance(springApplication));
System.out.println(springApplication);
banner
SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(
new DefaultResourceLoader(),
new SpringBootBanner()
);
ApplicationEnvironment applicationEnvironment = new ApplicationEnvironment();
applicationEnvironment.getPropertySources().addLast(new MapPropertySource("custom", ImmutableMap.of("spring.banner.location", "banner1.txt")));
System.out.println("SpringBootVersion:" + SpringBootVersion.getVersion());
bannerPrinter.print(applicationEnvironment, Step04.class, System.out);