记录一次ApplicationContext打入jar包后getBean空指针问题
项目中有两个服务,PC和H5,各自的工程代码里都有Service包。后来做代码优化,将service的包抽出来做了一个jar包,PC和H5的服务各自引用该jar包。原本service包在各自服务内部的时候没有问题,抽出来jar包再引用后就发现,使用ApplicationContext.getBean方法时,ApplicationContext报空指针,以下为项目中的代码结构以及解决方法。
在framework-common的jar包中有一个SpringContextUtils类,类中对ApplicationContext的方法进行了封装:
@Lazy(false) @Component("springContext") public class SpringContextUtils implements ApplicationContextAware { private static ApplicationContext context; private static boolean started=false; public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextUtils.context=applicationContext; started = true; } public static Object getBean(String name) throws BeansException { return context.getBean(name); } }
在另一个service-common的jar包中,对framework-common的jar包进行了引用,并在某个类中调用的SpringContextUtils.getBean方法:
@Slf4j @Component public class HandleStrategy { @Transactional(transactionManager = "tx", rollbackFor = Exception.class) public void exec(String id, Integer type) { long startTime = System.currentTimeMillis(); log.info("任务开始------------------------------------------"); final AbstractTypeHandler handler = (AbstractTypeHandler) SpringContextUtils.getBean(type); handler.handle(); log.info("完成:任务总执行时间为" + (System.currentTimeMillis() - startTime) + "毫秒"); }
结果就是获取AbstractTypeHandler的时候,SpringContextUtils类中一直报空指针。
从网上搜了一下,说是SpringContextUtils类放到本身的服务中是没问题的,打入到jar包中会有加载顺序的问题。但是奇怪的是,原来在服务中,SpringContextUtils类也是在framework-common的jar包中依赖进去的,是没有问题的。只是后来把服务的Service也抽出来打成了jar包,服务引用service-common的jar包,service-common引用framework-common的jar包,就有问题了。目前虽然解决了,但是不晓得具体原因是啥,还请路过的各位大神能解解惑。
贴一下解决方案吧,代码如下所示:
@Slf4j @Component @DependsOn("springContext") public class HandleStrategy { @Transactional(transactionManager = "tx", rollbackFor = Exception.class) public void exec(String id, Integer type) { long startTime = System.currentTimeMillis(); log.info("任务开始------------------------------------------"); final AbstractTypeHandler handler = (AbstractTypeHandler) SpringContextUtils.getBean(type); handler.handle(); log.info("完成:任务总执行时间为" + (System.currentTimeMillis() - startTime) + "毫秒"); }
在HandlerStrategy类上添加了@DependsOn注解,标注该类的加载将依赖SpringContextUtils类,springContext是SpringContextUtils类的名称,是第一段代码中SpringContextUtils类上面@Component中的名称。
读书小Tip:解读“囿”,总是觉得自己有了,却又看不到困在自己周围的笼子,好可怕~