spring中的扩展点总结

spring中的扩展点总结
在这里插入图片描述

finshBeanFactoryInitialization方法中会执行preInstantiateSingletons方法,其中会执行getBean方法,完成实例化,注入,初始化,销毁工作,具体流程如下
1)AbstractBeanFactory #doGetBean
1.1)getSingleton方法不为null则拿到了单实例,直接return,不执行下边逻辑;
1.2)getSingleton(beanName, () -> {return createBean(beanName, mbd, args);}
A)beforeSingletonCreation(beanName)
B)singletonObject = singletonFactory.getObject();
B.1)AbstractAutowireCapableBeanFactory #createBean
1.2.1)AbstractAutowireCapableBeanFactory #doCreateBean
1.2.1.1)createBeanInstance
a)determineConstructorsFromBeanPostProcessors
b)autowireConstructor
c) instantiateBean
1.2.1.2)applyMergedBeanDefinitionPostProcessors
1.2.1.3) addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))
1.2.1.4) populateBean
1.2.1.5)initializeBean
C)afterSingletonCreation(beanName);
D)addSingleton(beanName, singletonObject);
1.3)beforePrototypeCreation

情况一

在上述destroyBean方法中,单实例实现了DisposableBean接口后,容器在销毁时,会执行单实例中重写的destroy方法,在执行重写的destroy方法前,会检查是否有其他bean依赖了该bean,若有,则先销毁其他bean。
这里注意区分DisposableBean接口和DestructionAwareBeanPostProcessor接口,前者是在上述obtainFreshBeanFactory方法中调用,而后者是在finshBeanFactoryInitialization方法中调用,功能相似;

情况二

上述postProcessBeanFactory是一个空方法,留给子类实现,该方法是BeanFactoryPostProcessor接口中的一个方法,允许我们通过实现BeanFactoryPostProcessor 接口,在此处来插入我们定义的代码,同时还可以对当前容器中已注入的beanDefinition信息做任何操作;另外在执行postProcessBeanFactory之前,还可以实现BeanDefinitionRegistryPostProcessor接口,重写postProcessBeanDefinitionRegistry方法,可以执行自定义注解扫描逻辑等,可以在这里动态注册自己的beanDefinition,可以加载classpath之外的bean,在容器读取项目beanDefinition之后执行;其实postProcessBeanDefinitionRegistry也是继承了BeanFactoryPostProcessor,只是多了一个postProcessBeanDefinitionRegistry方法,可以拿到BeanDefinition;

情况三

invokeBeanFactoryPostProcessors查找 并 执行 bfpp 后处理器,该方法在加载完beanDefinition,实例化bean之前调用。可以拿到容器,修改bd信息;

情况四

在initializeBean方法中,主要执行四大块,首先通过applyBeanPostProcessorsBeforeInitialization 方法获取到容器中所有的BeanPostProcessor 类型的实例, 然后调用其postProcessBeforeInitialization 方法(完成对类中某些特殊方法的调用,比如@PostConstruct,Aware接口,以及自定义实现类),通过applyBeanPostProcessorsAfterInitialization 方法获取到容器中所有的BeanPostProcessor类型的实例, 然后调用其postProcessAfterInitialization方法(与aop相关),两个方法之间的逻辑是调用invokeInitMethods方法,该方法中会调用InitializingBean接口实现类中的 afterpropertiesSet方法,和执行init-method方法。所以最先执行的是postProcessBeforeInitialization方法,接着是afterPropertiesSet方法,然后是init-method指定的init方法,最后是postProcessAfterInitialization方法。关于这四个方法的具体区别见链接
https://www.codenong.com/9862127/;
afterPropertiesSet方法和init-method指定的init方法的区别详见
https://www.cnblogs.com/zsw1024520/p/13731548.html

根据业务场景不同,选择的扩展点也不同,如有时候需要在bean完成了实例化,注入后,完成某些判断,此时可以选择初始化前后执行该判断,例如需要对某些接口进行特殊处理;此时可以实现BeanPostProcessor接口,实现postProcessBeforeInitialization方法或者postProcessAfterInitialization方法;
如需要对加了自定义注解的类进行单独处理,此时可以自定义一个类实现BeanPostProcessor , Ordered接口,重写其中的postProcessBeforeInitialization和getOrder方法,在postProcessBeforeInitialization方法中判断当前bean的class类型中是否被该自定义的注解修饰,有的话就单独处理;但这个注解仅仅是标记作用,并不能将被修饰的类注入到容器中,所以要实现这一步,有三种做法;
第一种方式是在自定义注解中加@Component;
第二种方式是实现BeanDefinitionRegistryPostProcessor接口,重写postProcessBeanDefinitionRegistry方法,方法中拿到ClassPathBeanDefinitionScanner类型的实例,添加自定义注解的class类型到过滤器中(表示需要被扫描),执行doScan方法进行扫描注入,扫描路径就是当前包路径;
第三种方式是实现ImportBeanDefinitionRegistrar接口,重写registerBeanDefinitions方法,同样是拿到ClassPathBeanDefinitionScanner类型的实例,添加自定义注解的class类型到过滤器中(表示需要被扫描),执行doScan方法进行扫描注入,扫描路径就是当前包路径;但这种方式还要有个启动类,加上@Configuration注解,和@import(“实现类.class”);

情况五

包括生命周期中的调用接口,具体见生命周期那一节讲解;如InstantiationAwareBeanPostProcessor继承了BeanPostProcessor接口,多出了postProcessBeforeInstantiation,postProcessAfterInstantiation,postProcessPropertyValues这三个方法;而BeanPostProcessor接口中已有了postProcessBeforeInitialization和postProcessAfterInitialization方法;

情况六

最开始时可以自定义实现类实现ApplicationContextInitializer接口,重写initialize方法,用于最开始激活一些配置,容器刷新前,这时候spring容器还没被初始化,所以想要自己的扩展的生效,有以下三种方式:
a.在启动类中用springApplication.addInitializers(new TestApplicationContextInitializer())语句加入
b.配置文件配置context.initializer.classes=com.example.demo.TestApplicationContextInitializer
c.Spring SPI扩展,在spring.factories中加入org.springframework.context.ApplicationContextInitializer=实现类全路径包名;

情况七

容器启动完成后,会调用实现了LifeCycle接口的类中的方法,如可以实现项目启动后,去监听MQ中的某个topic,则可以这样实现,关闭时也可以实现该接口,在其方法中写业务逻辑;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

orcharddd_real

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值