Loading

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的类优先加载。

解决办法两个

  1. 最简单,但最奇葩

    1. Bean工具类示例
    @Component
    public class SpringUtils implements ApplicationContextAware {
    	// 还是老样子
    }
    
    1. 启动类添加注解注解@DependsOn(value = "SpringUtils")
      注:默认方式扫包必须保证SpringUtils在使用getBean文件的前边,例如同一个包下SpringUtils文件排在了前遍
  2. 比较常规的

    1. Bean工具类示例
    @Component //实测这个没有都行
    public class SpringUtils implements ApplicationContextAware {
    	// 还是老样子
    }
    
    1. 启动类添加注解注解@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) {
     	   		···
    		}
    }
    
    
posted @ 2021-10-13 18:06  WindSnowLi  阅读(477)  评论(0编辑  收藏  举报