SpringContextHelper或者SpringContextHolder之类命名的类,主要是通过Spring上下文根据bean名称获取注入spring的对象。代码相对简单,本文不对代码做详细赘述。主要mark使用过程中可能遇到的坑。
- 在项目启动时,可能会偶现SpringContextHelper抛出的NPE异常。那么什么情况会出现NPE呢?如bean A中有一个被@PostConstruct注解的方法m,当A被容器实例化之后会调用m,此时如果SpringContextHelper还未实例化就会导致NPE。最后虽然项目成功启动了,并且后续SpringContextHelper可以正常使用,但是这种NPE会导致m方法里面处理的数据出现丢失的情况。这种偶现的异常可能给项目带来失之毫厘差之千里的影响。
- 解决方案
知道报错原因我们很容易找到解决方法,只需要保证SpringContextHelper优先示例话即可。比如:
- 使用@DependsOn("springContextHelper"),在A上添加次注解,让A在SpringContextHelper之后实例化;
- 在spring包扫描时调整SpringContextHelper优先被扫描到。 (SpringContextHelper.java在com.bingo包路径下)
@ComponentScan(basePackages = { "com.bingo", "com.demo" })
- SpringContextHelper.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.Arrays;
/**
* <Description> 获取容器中的ApplicationContext<br>
*
* @author <br>
* @version 1.0<br>
* @taskId <br>
* @CreateDate 2016年10月10日 <br>
*/
@Component
public class SpringContextHelper implements ApplicationContextAware {
/**
* appCtx
*/
private static ApplicationContext appCtx;
/**
* Description: 此方法可以把ApplicationContext对象inject到当前类中作为一个静态成员变量。<br>
*
* @param applicationContext ApplicationContext 对象. <br>
* @author <br>
* @taskId <br>
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextHelper.setAppCtx(applicationContext);
}
/**
* Description: 此方法可以把ApplicationContext对象inject到当前类中作为一个静态成员变量。<br>
*
* @param applicationContext ApplicationContext 对象. <br>
* @author <br>
* @taskId <br>
*/
private static void setAppCtx(ApplicationContext applicationContext) {
appCtx = applicationContext;
}
/**
* Description: 获取ApplicationContext<br>
*
* @return <br>
* @author <br>
* @taskId <br>
*/
public static ApplicationContext getApplicationContext() {
return appCtx;
}
/**
* Description:这是一个便利的方法,帮助我们快速得到一个BEAN <br>
*
* @param beanName beanName
* @return <br>
* @author <br>
* @taskId <br>
*/
public static Object getBean(String beanName) {
return appCtx.getBean(beanName);
}
/**
* Description: 快速获取Spring容器中的bean<br>
*
* @param <T> <br>
* @param clazz <br>
* @return <br>
* @author <br>
* @taskId <br>
*/
public static <T> T getBean(Class<T> clazz) {
return appCtx.getBean(clazz);
}
/**
* 打印所有的bean name <br>
*/
public static void printAllBeans() {
System.out.println(Arrays.asList(appCtx.getBeanDefinitionNames()));
}
}