SpringBoot调整ApplicationContextAware实现类加载顺序问题
简介
自己需要在项目中使用redis-cache
插件,但是官方放出来的包太老了,仓库代码更新倒是还可以,所以打算自己封装下,修改下加载配置文件的方式。
需求
有时候需要在普通类获取到Bean
,但是new
出来的对象不会被注入,这时就需要通过SpringBoot
上下文去获取Bean,思路很简单,实现ApplicationContextAware
后在类上加个@Componse
注解就可以很容易的实现加载上下文,例如
@Component
public 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
的类优先加载。
解决办法两个
-
最简单,但最奇葩
Bean
工具类示例
@Component public class SpringUtils implements ApplicationContextAware { // 还是老样子 }
- 启动类添加注解注解
@DependsOn(value = "SpringUtils")
注:默认方式扫包必须保证SpringUtils
在使用getBean
文件的前边,例如同一个包下SpringUtils
文件排在了前遍
-
比较常规的
Bean
工具类示例
@Component //实测这个没有都行 public class SpringUtils implements ApplicationContextAware { // 还是老样子 }
- 启动类添加注解注解
@Import(SpringUtils.class)
,并强依赖使用
··· 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) { ··· } }