SpringBoot|SpringBoot 钩子接口的实现代码

目录

  • Aware 接口族
  • InitializingBean
  • BeanPostProcessor
  • BeanFactoryPostProcessor
  • ImportSelector
  • ImportBeanDefinitionRegistrar
  • FactoryBean
  • ApplicationListener
  • ApplicationRunner

Aware 接口族 Aware 意为感知,实现 Aware 接口并重写其方法,可以从上下文中获取当前的运行环境
常见的 aware 接口
  • BeanNameAware
  • BeanFactoryAware
  • BeanClassLoaderAware
  • ApplicationContextAware
使用

@Component@ToStringpublic class TestServiceimplements BeanNameAware, BeanClassLoaderAware {private String beanName; private ClassLoader classLoader; @Overridepublic void setBeanClassLoader(ClassLoader classLoader) {this.classLoader = classLoader; }@Overridepublic void setBeanName(String name) {this.beanName= name; }}


InitializingBean InitializingBean 接口用于在 Bean 的初始化阶段执行自定义的操作,类型功能的还有 DisposableBean
使用

@Componentpublic class TestBean implements InitializingBean, DisposableBean {// bean 设置完属性之后调用@Overridepublic void afterPropertiesSet() throws Exception {// 初始化操作System.out.println("TestBean init"); }// 销毁之后调用@Overridepublic void destroy() throws Exception {// 释放资源System.out.println("TestBean destroy"); }}


BeanPostProcessor BeanPostProcessor,Bean 的后置处理器,与 InitializingBean 不同的是,BeanPostProcessor 对所有 Bean 生效
使用

@Componentpublic class TestPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("Bean 初始化前"); return bean; }@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("Bean 初始化后"); return bean; }}

BeanPostProcessor 使用场景非常多,可以获取正在初始化的 Bean 对象,然后依据该 Bean 对象做一些定制化的操作,如:判断该 Bean 是否为某个特定对象、获取 Bean 的注解元数据等
Spring 内置了非常多的 BeanPostProcessor ,以此来完善自身功能

BeanFactoryPostProcessor BeanFactoryPostProcessor 是 Bean 工厂的后置处理器,一般用来修改上下文中的 BeanDefinition
使用

@Componentpublic class TestFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("所有 BeanDefinition 已被加载,但还未实例化 Bean"); // 动态添加 BeanDefinition//转换为子类 DefaultListableBeanFactoryDefaultListableBeanFactory defaultBeanFactory = (DefaultListableBeanFactory) beanFactory; //new 一个 beanDefinition对象GenericBeanDefinition b = new GenericBeanDefinition(); b.setBeanClass(Testbean.class); //添加一个 beanDefinition 对象defaultBeanFactory.registerBeanDefinition("testBean", b); // 动态获取 BeanDefinitionObject o = defaultBeanFactory.getBean("testBean")}}

BeanDefinition 包含了 Spring 实例化一个 Bean 的所需的信息

ImportSelector ImportSelector 可以动态的返回需要被容器管理的类,一般用来返回外部的配置类

public class TestImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {// AnnotationMetadata 存储注解元数据信息// 可以动态的返回需要被容器管理的类名称if (importingClassMetadata.hasAnnotation("")) {// 判断是否包含某个注解}// TestBean 加入到 Spring 容器中return new String[]{"com.example.pojo.TestBean"}; }}

在标注 @Configuration 注解的类中,通过 @Import 导入 ImportSelector 来使之生效

@Configuration@Import(TestImportSelector.class)public class TestConfig {}


ImportBeanDefinitionRegistrar ImportBeanDefinitionRegistrar 也是配合 @Import 使用,可直接将 Bean 注册到容器中
使用

public class TestRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,BeanDefinitionRegistry registry) {GenericBeanDefinition b = new GenericBeanDefinition(); b.setBeanClass(NotScanBean.class); b.setLazyInit(true); // 注册到容器中registry.registerBeanDefinition(NotScanBean.class.getName(), b); }}


FactoryBean FactoryBean 为创建 Bean 提供了更加灵活的方式,常用于用于创建一类 Bean
Bean 实现 FactoryBean 后,通过 getBean(String BeanName) 获取到的 Bean 对象并不是 FactoryBean 的实现类对象,而是这个实现类中的 getObject() 方法返回的对象,在 BeanName 之前加上 &,可以获取 FactoryBean 的实现类对象
使用

@Componentpublic class TestFactoryBean implements FactoryBean {@Overridepublic TestBean getObject() throws Exception {// 对 Bean 进行配置// 如代理、修饰等return new TestBean(); }@Overridepublic Class getObjectType() {return null; }}


ApplicationListener 【SpringBoot|SpringBoot 钩子接口的实现代码】ApplicationListener 是 Spring 实现事件机制的核心接口,属于观察者设计模式
ApplicationContext 可以发布 ApplicationEvent 事件,之后所有的 ApplicationListener 会被回调
自定义 ApplicationEvent

public class TestApplicationEvent extends ApplicationEvent {public TestApplicationEvent(Object source) {super(source); }public void hello(){System.out.println("Hello Word!"); }}

自定义 ApplicationListener

@Componentpublic class TestApplicationListener implements ApplicationListener {@Overridepublic void onApplicationEvent(ApplicationEvent event) {if (event instanceof TestApplicationEvent) {TestApplicationEvent testApplicationEvent = (TestApplicationEvent) event; testApplicationEvent.hello(); }}}

通过注入 ApplicationContext 或实现 ApplicationContextAware 接口,获取 ApplicationContext 对象,发布 ApplicationEvent

@SpringBootTestclass DemoApplicationTests {@AutowiredApplicationContext applicationContext; @Testpublic void test() {applicationContext.publishEvent(new TestApplicationEvent(new DemoApplication())); }}// Hello Word!


ApplicationRunner SpringBoot 应用启动成功会 callRunners 方法,所有 ApplicationRunner 实现类都会被回调
实现 AppilcationRunner,ApplicationArguments 类型用来接收启动参数

@Componentpublic class MyApplicationRunner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {System.out.println("原始参数:" + Arrays.asList(args.getSourceArgs())); Set keys = args.getOptionNames(); for (String key : keys) {System.out.println("解析后的 key: [" + key + "]value: " + args.getOptionValues(key)); }System.out.println("无 OptionName 的参数: " + args.getNonOptionArgs()); }}// 例:启动参数 --a=1 --b c// 打印 =>// 原始参数:[--a=1, --b, c]// 解析后的 key: [a]value: [1]// 解析后的 key: [b]value: []// 无 OptionName 的参数: [c]

CommandLineRunner 和 ApplicationRunner 类似,但是只能获得没有经过解析的原始参数

到此这篇关于SpringBoot 钩子接口的实现代码的文章就介绍到这了,更多相关SpringBoot 钩子接口内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    推荐阅读