以下都是博主自己亲身经历的,希望能够帮到遇到同样问题的同学!
**背景:**开发一个调度,实现多种类型异常工单的统计
实现方式:
1、定义通用接口:异常工单统计
public interface WorkExceptionService {
List<WorkExceptionEntity> getWorkException() throws Exception;
}
2、分别定义多个实现类,每一个实现类就代表一种异常工单
@Service("ThirdExceptionWorksImpl ")
public class ThirdExceptionWorksImpl implements WorkExceptionService{
@Autowired
private WorkExceptionMapper mapper;
@Override
public List<WorkExceptionEntity> getWorkException() {
List<WorkExceptionEntity> thirdList = new ArrayList<>();
List<WorkExceptionEntity> list = mapper.getThirdExceptionWorks();
if(list.isEmpty()) {
return new ArrayList<>();
}
3、类对象赋值给接口引用的方法
WorkExceptionService workService ;
workService = new ThirdExceptionWorksImpl();
workService.getWorkException();
注意了,此时不会走Spring的@Autowired自动注入,从而导致在ThirdExceptionWorksImpl 中调用mapper接口时,如下:
List list = mapper.getThirdExceptionWorks();
这就会出现mapper为null的情况,那么null调用后面的getThirdExceptionWorks();方法,肯定报错了。
解决办法:
首先需要引入Spring容器帮助类(SpringContextUtil),实现ApplicationContextAware接口
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringContextUtil.applicationContext == null) {
SpringContextUtil.applicationContext = applicationContext;
}
}
/**
* 获取applicationContext
*
* @return
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 通过name获取 Bean.
*
* @param name
* Bean's name
* @return
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通过class获取Bean.
*
* @param clazz
* @return
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通过name,以及Clazz返回指定的Bean
*
* @param name
* @param clazz
* @return
*/
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
从该实现类中可以看到,获取Bean的方式主要有三种:
1、通过实现类的name获取 Bean.
2、通过class获取Bean.
3、通过name,以及class返回指定的Bean.
我这里以通过实现类的name获取Bean的方式为例,其余两种方式就留给感兴趣的同学自己去研究了。
具体使用:
1、在引用的类中声明接口对象(workService ),并且指定具体的实现类(ThirdExceptionWorksImpl):
WorkExceptionService workService = (WorkExceptionService) SpringContextUtil.getBean(“ThirdExceptionWorksImpl”);
2、调用实现类重写的接口:
WorkExceptionService workService = (WorkExceptionService) SpringContextUtil.getBean(“ThirdExceptionWorksImpl”);
workService.getWorkException();
3、在实现类上添加上注解:@Service(“ThirdExceptionWorksImpl”),指定其实现类,名字自定义,确保与1中.getBean(" ")中的一致即可。
这样就能完美的解决这个问题了!!!