ApplicationContextInitializer
SpringBoot 框架在设计之初,为了有更好的兼容性,在不同的运行阶段,提供了非常多的可扩展点,可以让程序员根据自己的需求,在整个Spring应用程序运行过程中执行程序员自定义的代码ApplicationContextInitializer就是众多扩展点中的一个扩展点
执行时机
ApplicationContextInitializer在IOC容器对象创建完成后执行,可以对上下文环境做一些操作,例如运行环境属性注册等
使用
1.自定义类,实现ApplicationContextInitializer接口
public class MyApplicationcontextInitializer implements ApplicationContextInitializer {//ioc容器对象创建完毕后执行@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {//给上下文context对象注入环境属性//1.准备属性Map<String, Object> protMap = new HashMap<>();protMap.put("applicationName","chessman");//2.获取一个属性资源管理对象//获取的环境独享ConfigurableEnvironment environment = applicationContext.getEnvironment();//属性资源管理对象MutablePropertySources propertySources = environment.getPropertySources();//3.注册propertySources.addLast(new MapPropertySource("proMap",protMap));}
}
2.在META-INF/spring.factories配置文件中配置自定义的类
#接口全路径名称=自定义类的全路径名称 自动补全路径:ctrl+alt+空格
org.springframework.context.ApplicationContextInitializer = com.cacb.initializer.MyApplicationcontextInitializer
最后在启动类中测试一下
@SpringBootApplication
public class APP {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(APP.class, args);String applicationName = context.getEnvironment().getProperty("applicationName");System.out.println(applicationName);}
}
执行结果:
可以看到,我们写的application方法已经得到运行
ApplicationListener
监听容器发布的事件,允许程序员执行自己的代码,完成事件驱动开发,它可以监听容器初始化完成、初始化失败等事件。通常情况下可以使用监听器加载资源,开启定时任务等
使用
1.自定义类,实现ApplicationListener接口
public class MyListener implements ApplicationListener {@Overridepublic void onApplicationEvent(ApplicationEvent event) {//ApplicationEvent event 对应的就是发布的事件,ApplicationReadyEvent成功,ApplicationFailedEvent失败if (event instanceof ApplicationReadyEvent){//容器初始化成功System.out.println("MyListener 容器初始化成功");}if (event instanceof ApplicationFailedEvent){//容器初始化失败System.out.println("MyListener 容器初始化失败");}}
}
2.在META-INF/spring.facoytries配置文件中配置自定义的类
org.springframework.context.ApplicationListener = com.cacb.listener.MyListener
运行启动类,查看容器是否成功初始化
正常情况:
在applicationcontextinitializer中通过1/0制造一个异常,再次运行,看容器是否能成功初始化
容器初始化失败,符合上面写的逻辑判断
执行时机
IOC容器发布事件之后执行,通常用于资源加载、定时任务发布等
BeanFactory
Bean容器的根接口,提供Bean对象的创建、配置、依赖注入等功能
常用实现类
最常见的两个实现:
ApplicationConfigServletApplicationContext
DefaultListabkeBeanFactory
BeanDefinition
用于描述Bean,包括Bean的名称,Bean的属性,Bean的行为,实现的接口,添加的注解等等。Spring中,Bean在创建之前,都需要封装成对应的BeanDefinition,然后根据BeanDefinition进一步创建Bean对象
接口继承体系
BeanFactoryPostProcessor
Bean工厂后置处理器,当BeanFactory准备好了以后(Bean初始化之前),会调用该接口i的postProcessBeanFactory方法,经常用于新增BeanDefinition
使用
自定义类实现BeanFactoryPostProcessor接口,在其中注册BeanDefinition
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {//当BeanFactory被实例化好后(Bean创建之前),回调这个函数,注册一些BeanDefinition@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {//注册一个people的BeanDifinitiomGenericBeanDefinition gbdf = new GenericBeanDefinition();gbdf.setBeanClass(people.class);//向下强转DefaultListableBeanFactory dbf = (DefaultListableBeanFactory) beanFactory;dbf.registerBeanDefinition("people",gbdf);}
}
Aware
感知接口,Spring提供的一种机制,通过实现该接口,重写方法,可以感知Spring应用程序执行过程中的一些变化。Spring会判断当前的Bean有没有实现Aware接口,如果实现了,会在特定的实际回调接口对应的方法。
使用
自定义类,继承三个接口,使用@Compent注解来让Spring自动注册该Bean
@Component
public class child implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {//BeanClassLoaderAware接口的回调方法@Overridepublic void setBeanClassLoader(ClassLoader classLoader) {System.out.println("child setBeanClassLoader "+classLoader);}//BeanFactoryAware接口的回调方法@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("child setBeanFactory "+beanFactory);}//BeanNameAware接口的回调方法@Overridepublic void setBeanName(String name) {System.out.println("child setBeanName "+name);}
}
InitializingBean/DisposableBean
初始化接口,当Bean被实例化好后,会回调里面的函数,经常用于做一些加载资源的工作
销毁接口,当Bean被销毁之前,会回调里面的函数,经常用于做一些资源释放的工作
使用
自定义类,继承两个接口,重写相关方法,使用@Compent注解来让Spring自动注册该Bean
@Component
public class student implements InitializingBean , DisposableBean {//销毁方法@Overridepublic void destroy() throws Exception {System.out.println("student destroy");}//初始化方法@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("student afterPropertiesSet");}
}
也可以用@PostConstruct和@PreDestroy两个注解来书写初始化和销毁方法,且如果注解对应方法和实现的接口方法同时存在,会先运行注解对应的方法,再运行实现的接口方法(初始化和销毁时都是)
@PostConstructpublic void init(){System.out.println("student PostConstruct");}@PreDestroypublic void destroy_method(){System.out.println("student destroy_method");}
BeanPostProcessor
Bean的后置处理器,当Bean对象初始化之前及初始化之后,会回调该接口对应的方法,两个方法如下:
postProcessBeforeInitialization: Bean对象初始化之前调用
postProcessAfterInitialization: Bean对象初始化之后调用
使用
自定义类,实现BeanPostProcessor接口,重写 两个方法,通过@Componet将其交给IOC容器
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {//初始化之前调用@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("MyBeanPostProcessor---BeforeInitialization---"+beanName);return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);}//初始化之后调用@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("MyBeanPostProcessor---AfterInitialization---"+beanName);return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);}
}