文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

SpringBoot 钩子接口的实现代码

2024-04-02 19:55

关注

Aware 接口族

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

常见的 aware 接口

使用


@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 钩子接口内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯