SpringBoot调整ApplicationContextAware实现类加载顺序问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
SpringBoot调整ApplicationContextAware实现类加载顺序
自己需要在项目中使用redis-cache插件,但是官方放出来的包太老了,仓库代码更新倒是还可以,所以打算自己封装下,修改下加载配置文件的方式。
需求
有时候需要在普通类获取到Bean,但是new出来的对象不会被注入,这时就需要通过SpringBoot上下文去获取Bean,思路很简单,实现ApplicationContextAware后在类上加个@Componse注解就可以很容易的实现加载上下文
例如:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@Componentpublic class SpringUtils implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringUtils.applicationContext = applicationContext; } public static ApplicationContext getApplicationContext(){ return applicationContext; } public static Object getBean(String name) { return applicationContext.getBean(name); } public static <T> T getBean(Class<T> clazz) { return applicationContext.getBean(clazz); }} |
思路很简单,但是有个坑,有时使用到getBean的地方可能applicationContext还没被注入,这时会报空指针错误,但是在测试中又能正确注入,很是恼火。
坑
本机使用Ubuntu+IDEA开发,由maven进行构建,本地环境以及版本与目标环境一致,但是构建出来的包(md5)不一样,本地构建出来的包可以在本地以及目标环境运行,但是直接在目标环境构建的在哪都会报applicationContext空指针错误,可能某些潜在原因,导致编译结果不一致,不过既然本地可以正常运行,那么肯定有解决办法。
解决思路
通过调试发现使用getBean的地方比注入ApplicationContext要早,最终也会注入,所以解决思路就是让需要ApplicationContext的类优先加载。
解决办法两个
1.最简单,但最奇葩
Bean工具类示例
|
1
2
3
4
|
@Componentpublic class SpringUtils implements ApplicationContextAware { // 还是老样子} |
启动类添加注解注解@DependsOn(value = "SpringUtils")
注:默认方式扫包必须保证SpringUtils在使用getBean文件的前边,例如同一个包下SpringUtils文件排在了前遍
2.比较常规的
Bean工具类示例
|
1
2
3
4
|
@Component //实测这个没有都行public class SpringUtils implements ApplicationContextAware { // 还是老样子} |
启动类添加注解注解@Import(SpringUtils.class),并强依赖使用
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
···import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Import;······@Import(SpringUtils.class)public class LBlogApplication { @Autowired public void setRedisConfigurationBuilder(RedisConfigurationBuilder redisConfigurationBuilder) { // 为了优先加载 } public static void main(String[] args) { ··· }} |
ApplicationContextAware加载顺序遇到的问题
公司使用的是自主研发的框架,类似ibatis,封装可统一的list查询接口,自定义SpringBeanFactory实现ApplicationContextAware获取spring上下文对象。
问题
之前在mvc环境下使用一直没有问题,最近切换成springboot框架,系统启动时list接口类会调用SpringBeanFactory的getbean方法注入一个bean,发现SpringBeanFactory的set方法还没有调用,就是系统还没有扫描到SpringBeanFactory对象;
开始在list接口类上加@Lazy注解,调用到当前类时再初始化,可以解决当前问题,后期发现这个类还有静态变量,其他地方要用到,如果没有调到这个接口他的静态变量使用是否会有问题?静态代码块是否执行?(时间问题,没有测试)考虑到这些问题,决定不使用@Lazy注解,百度一下发现
|
1
|
@DependsOn(value = “springBeanFactory”) |
可以解决这个问题。