这种方式是最灵活的 , 能在registerBeanDefinitions
方法中获取到BeanDefinitionRegistry
容器注册对象,可以手动控制BeanDefinition的创建和注册 。
6.项目启动时有时候我们需要在项目启动时定制化一些附加功能 , 比如:加载一些系统参数、完成初始化、预热本地缓存等,该怎么办呢?
好消息是springboot提供了:
- CommandLineRunner
- ApplicationRunner
它们的用法还是挺简单的,以
ApplicationRunner
接口为例:@Componentpublic class TestRunner implements ApplicationRunner {@Autowiredprivate LoadDataService loadDataService;public void run(ApplicationArguments args) throws Exception {loadDataService.load();}}
实现ApplicationRunner
接口,重写run
方法,在该方法中实现自己定制化需求 。如果项目中有多个类实现了ApplicationRunner接口,他们的执行顺序要怎么指定呢?
答案是使用
@Order(n)
注解 , n的值越小越先执行 。当然也可以通过@Priority
注解指定顺序 。7.修改BeanDefinitionSpring IOC在实例化Bean对象之前 , 需要先读取Bean的相关属性 , 保存到
BeanDefinition
对象中,然后通过BeanDefinition对象,实例化Bean对象 。如果想修改BeanDefinition对象中的属性,该怎么办呢?
答:我们可以实现
BeanFactoryPostProcessor
接口 。@Componentpublic class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);beanDefinitionBuilder.addPropertyValue("id", 123);beanDefinitionBuilder.addPropertyValue("name", "苏三说技术");defaultListableBeanFactory.registerBeanDefinition("user", beanDefinitionBuilder.getBeanDefinition());}}
在postProcessBeanFactory方法中,可以获取BeanDefinition的相关对象,并且修改该对象的属性 。8.初始化Bean前后有时,你想在初始化Bean前后,实现一些自己的逻辑 。
这时可以实现:
BeanPostProcessor
接口 。该接口目前有两个方法:
- postProcessBeforeInitialization 该在初始化方法之前调用 。
- postProcessAfterInitialization 该方法再初始化方法之后调用 。
@Componentpublic class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof User) {((User) bean).setUserName("苏三说技术");}return bean;}}
如果spring中存在User对象,则将它的userName设置成:苏三说技术 。其实,我们经常使用的注解 , 比如:@Autowired、@Value、@Resource、@PostConstruct等,是通过AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor实现的 。
9.初始化方法目前spring中使用比较多的初始化bean的方法有:
- 使用@PostConstruct注解
- 实现InitializingBean接口
@Servicepublic class AService {@PostConstructpublic void init() {System.out.println("===初始化===");}}
在需要初始化的方法上增加@PostConstruct
注解 , 这样就有初始化的能力 。9.2 实现InitializingBean接口
@Servicepublic class BService implements InitializingBean {@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("===初始化===");}}
实现InitializingBean
接口 , 重写afterPropertiesSet
方法 , 该方法中可以完成初始化功能 。10.关闭容器前有时候,我们需要在关闭spring容器前,做一些额外的工作,比如:关闭资源文件等 。
这时可以实现
DisposableBean
接口,并且重写它的destroy
方法:@Servicepublic class DService implements InitializingBean, DisposableBean {@Overridepublic void destroy() throws Exception {System.out.println("DisposableBean destroy");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("InitializingBean afterPropertiesSet");}}
这样spring容器销毁前 , 会调用该destroy方法,做一些额外的工作 。通常情况下,我们会同时实现InitializingBean和DisposableBean接口 , 重写初始化方法和销毁方法 。
11.自定义作用域我们都知道spring默认支持的
推荐阅读
- Spring Cloud Consul 入门指引
- 原神怎么让正机之神瘫痪
- 一个 dubbo 和 springboot 的兼容性问题
- 一篇文章带你掌握主流基础框架——Spring
- 【持久层框架】- SpringData - JPA
- SpringBoot的starter到底是什么?
- Springboot 之 HandlerMethodReturnValueHandler 运用
- Spring mvc源码分析系列--Servlet的前世今生
- spring cron表达式源码分析
- QQ怎么建群啊(qq建群怎么让人变多)