服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - SpringBoot 钩子接口的实现代码

SpringBoot 钩子接口的实现代码

2021-11-29 12:04CadeCode Java教程

本文主要介绍了SpringBoot 钩子接口,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

Aware 接口族

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

常见的 aware 接口

  • BeanNameAware
  • BeanFactoryAware
  • BeanClassLoaderAware
  • ApplicationContextAware

使用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@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

使用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@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 生效

使用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@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

使用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@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 可以动态的返回需要被容器管理的类,一般用来返回外部的配置类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 来使之生效

?
1
2
3
4
@Configuration
@Import(TestImportSelector.class)
public class TestConfig {
}

ImportBeanDefinitionRegistrar

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

使用

?
1
2
3
4
5
6
7
8
9
10
11
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 的实现类对象

使用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@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

?
1
2
3
4
5
6
7
8
9
10
public class TestApplicationEvent extends ApplicationEvent {
 
    public TestApplicationEvent(Object source) {
        super(source);
    }
 
    public void hello(){
        System.out.println("Hello Word!");
    }
}

自定义 ApplicationListener

?
1
2
3
4
5
6
7
8
9
10
11
@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

?
1
2
3
4
5
6
7
8
9
10
11
12
@SpringBootTest
class DemoApplicationTests {
 
    @Autowired
    ApplicationContext applicationContext;
 
    @Test
    public void test() {
        applicationContext.publishEvent(new TestApplicationEvent(new DemoApplication()));
    }
}
// Hello Word!

ApplicationRunner

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@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 钩子接口内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://juejin.cn/post/6998887774614978573

延伸 · 阅读

精彩推荐
  • Java教程Java map的学习及代码示例

    Java map的学习及代码示例

    这篇文章主要介绍了Java map的学习及代码示例,简单介绍了map与collection的比较,map的相关内容,分享了map的一些简介代码示例,具有一定参考价值,需要的...

    fightingKing11492021-02-06
  • Java教程Kafka简单客户端编程实例

    Kafka简单客户端编程实例

    这篇文章主要为大家详细介绍了Kafka简单客户端编程实例,利用Kafka的API进行客户端编程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    liuyazhuang7122021-02-01
  • Java教程Java中stream处理中map与flatMap的比较和使用案例

    Java中stream处理中map与flatMap的比较和使用案例

    这篇文章主要介绍了Java中stream处理中map与flatMap的比较和使用案例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,...

    Listen-Y5402021-08-26
  • Java教程SpringBoot项目整合mybatis的方法步骤与实例

    SpringBoot项目整合mybatis的方法步骤与实例

    今天小编就为大家分享一篇关于SpringBoot项目整合mybatis的方法步骤与实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一...

    双斜杠少年4452021-07-21
  • Java教程SpringMVC的工程搭建步骤实现

    SpringMVC的工程搭建步骤实现

    这篇文章主要介绍了SpringMVC的工程搭建步骤实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面...

    Ai清5542021-09-02
  • Java教程SpringBoot2.0 ZipKin示例代码

    SpringBoot2.0 ZipKin示例代码

    这篇文章主要介绍了SpringBoot2.0 ZipKin示例代码,详细的介绍了什么是ZipKin以及SpringBoot2.0 ZipKin示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    攻城遭雷劈11152021-06-11
  • Java教程学习Java多线程之同步

    学习Java多线程之同步

    这篇文章主要为大家详细介绍了Java多线程之同步,感兴趣的小伙伴们可以参考一下 ...

    刘望舒2672020-04-06
  • Java教程详解Java反射各种应用

    详解Java反射各种应用

    Java除了给我们提供在编译期得到类的各种信息之外,还通过反射让我们可以在运行期间得到类的各种信息。通过反射获取类的信息,得到类的信息之后,就...

    byhieg4092020-07-24