好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

查看更多关于SpringBoot 钩子接口的实现代码的详细内容...

  阅读:16次