SpringBoot 钩子接口的实现代码

 更新时间:2021年08月22日 17:23:37   作者:CadeCode  
本文主要介绍了SpringBoot 钩子接口,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

Aware 接口族

Aware 意为感知,实现 Aware 接口并重写其方法,可以从上下文中获取当前的运行环境

常见的 aware 接口

  • BeanNameAware
  • BeanFactoryAware
  • BeanClassLoaderAware
  • ApplicationContextAware

使用

@Component
@ToString
public class TestService  implements BeanNameAware, BeanClassLoaderAware {
    private String beanName;
    private ClassLoader classLoader;

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

    @Override
    public void setBeanName(String name) {
        this.beanName= name;
    }

}

InitializingBean

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

使用

@Component
public class TestBean implements InitializingBean, DisposableBean {

    // bean 设置完属性之后调用
    @Override
    public void afterPropertiesSet() throws Exception {
        // 初始化操作
        System.out.println("TestBean init");
    }

    // 销毁之后调用
    @Override
    public void destroy() throws Exception {
        // 释放资源
        System.out.println("TestBean destroy");
    }
}

BeanPostProcessor

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

使用

@Component
public class TestPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Bean 初始化前");
        return bean;
    }

    @Override
    public 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

使用

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

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

ImportSelector

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

public class TestImportSelector implements ImportSelector {
    @Override
    public 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 {
    @Override
    public 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 的实现类对象

使用

@Component
public class TestFactoryBean implements FactoryBean<TestBean> {
    @Override
    public TestBean getObject() throws Exception {

        // 对 Bean 进行配置
        // 如代理、修饰等

        return new TestBean();
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }
}

ApplicationListener

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

@Component
public class TestApplicationListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof TestApplicationEvent) {
            TestApplicationEvent testApplicationEvent = (TestApplicationEvent) event;
            testApplicationEvent.hello();
        }
    }
}

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

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    ApplicationContext applicationContext;

    @Test
    public void test() {
        applicationContext.publishEvent(new TestApplicationEvent(new DemoApplication()));
    }
}
// Hello Word!

ApplicationRunner

SpringBoot 应用启动成功会 callRunners 方法,所有 ApplicationRunner 实现类都会被回调

实现 AppilcationRunner,ApplicationArguments 类型用来接收启动参数

@Component
public class MyApplicationRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("原始参数:" + Arrays.asList(args.getSourceArgs()));
        Set<String> 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 钩子接口内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot实现异步调用的方法示例

    SpringBoot实现异步调用的方法示例

    本文介绍了在Java的SpringBoot中实现异步请求和异步调用的几种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-01-01
  • Java打印九九乘法表代码详情

    Java打印九九乘法表代码详情

    这篇文章主要介绍了Java打印九九乘法表,使用了双重for循环,使用do{}while()实现打印九九乘法表这些好玩的语法实现,感兴趣的小伙伴可参考下面文章内容
    2021-09-09
  • Java如何防止JS脚本注入代码实例

    Java如何防止JS脚本注入代码实例

    这篇文章主要介绍了Java如何防止JS脚本注入代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • 简单了解JAVA public class与class区别

    简单了解JAVA public class与class区别

    这篇文章主要介绍了简单了解JAVA public class与class区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • 浅谈SpringMVC对RESTfull的支持

    浅谈SpringMVC对RESTfull的支持

    这篇文章主要介绍了浅谈SpringMVC对RESTfull的支持,分享了相关配置代码,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • 使用java实现百万级别数据导出excel的三种方式

    使用java实现百万级别数据导出excel的三种方式

    这篇文章主要介绍了使用java实现百万级别数据导出excel的三种方式,有些业务系统可能动辄涉及到百万上千万的数据,用正常的方法效率就变得很低,今天我们来看看这几种实现思路
    2023-03-03
  • IDEA提示内存不足low memory的错误解决

    IDEA提示内存不足low memory的错误解决

    运行项目变得很卡,这种情况比较能直观感受出来,Idea内存指示器,则需要设置才能看到,本文主要介绍了IDEA提示内存不足low memory的错误解决,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • JVM 方法调用之动态分派(详解)

    JVM 方法调用之动态分派(详解)

    下面小编就为大家带来一篇JVM 方法调用之动态分派(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • IntelliJ IDEA版Postman强大功能介绍

    IntelliJ IDEA版Postman强大功能介绍

    这篇文章主要为大家介绍了IDEA版Postman的强大功能介绍,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • java随机生成一个名字和对应拼音的方法

    java随机生成一个名字和对应拼音的方法

    这篇文章主要介绍了java随机生成一个名字和对应拼音的方法,涉及java针对数组及随机数操作的相关技巧,需要的朋友可以参考下
    2015-07-07

最新评论