问题:
RunLoad类中:使用@Autowired为analyzeSourceData,dao,sysDicDao注入值但均为null
@Component
public class RunLoad {
private static final Logger log = LogManager.getLogger(RunLoad.class);
@Autowired
private AnalyzeSourceDataMong analyzeSourceData;
@Autowired
private MongodbDao dao;
@Autowired
private SysDicDao sysDicDao;
public void run(DownLoadRepository downLoadRepository) {
//业务代码省略
}
}
解决:
一、先检查spring是否已经实例化 了 AnalyzeSourceDataMong ,MongodbDao ,SysDicDao 。
方法:在main方法使用getBeanDefinitionNames()方法打印出spring容器中的实例化的对象,代码如下
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(Main.class, args);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String string : beanDefinitionNames) {
System.out.println(string);
}
DownLoadIFace downLoadIFace = applicationContext.getBean(DownLoadIFace.class);
downLoadIFace.exectute();
}
二、确认已经实例化之后,由于是在DownLoadIFaceImpl类中调用的RunLoad类的run方法,因此检查DownLoadIFaceImpl类
在这个类中发现我是手动new RunLoad(),代码如下:
@Component
public class DownLoadIFaceImpl implements DownLoadIFace{
@Autowired
private DownLoadRepositoryDao downLoadRepositoryDao;
@Value("${sftp.port}")
private String sftpPort;
@Scheduled(cron = "${quartz.CronExpression}")
@Override
public void exectute() {
RunLoad runLoad= new RunLoad();
List<DownLoadRepository> downLoadRepositorys = this.downLoadRepositoryDao.findAll();
if(downLoadRepositorys!=null) {
for (DownLoadRepository downLoadRepository : downLoadRepositorys) {
if("XML".equalsIgnoreCase(downLoadRepository.getDownloadType())) {
runLoad.run(downLoadRepository);
}else if("SERVER-BOOK".equalsIgnoreCase(downLoadRepository.getDownloadType())) {
//TODO 确定参数是否是固定值
String host = downLoadRepository.getSourceUrl();
int port = Integer.parseInt(sftpPort);
String username = downLoadRepository.getSourceUsername();
String password = downLoadRepository.getSourceUrl();
BcmSFTPUtils sftpUtils = new BcmSFTPUtils(host, port, username, password);
FileConvertConstant.sftp = sftpUtils;
}
}
}
}
然后,我也不知道为什么就感觉可是因为自己手动new的原因导致注入为null,接着我就将RunLoad也改为了@Autowired注入,代码如下:
@Component
public class DownLoadIFaceImpl implements DownLoadIFace{
@Autowired
private DownLoadRepositoryDao downLoadRepositoryDao;
@Autowired
private RunLoad runLoad;
@Autowired
private ExecuteConvert executeConvert;
@Value("${sftp.port}")
private String sftpPort;
@Scheduled(cron = "${quartz.CronExpression}")
@Override
public void exectute() {
List<DownLoadRepository> downLoadRepositorys = this.downLoadRepositoryDao.findAll();
if(downLoadRepositorys!=null) {
for (DownLoadRepository downLoadRepository : downLoadRepositorys) {
if("XML".equalsIgnoreCase(downLoadRepository.getDownloadType())) {
runLoad.run(downLoadRepository);
}else if("SERVER-BOOK".equalsIgnoreCase(downLoadRepository.getDownloadType())) {
//TODO 确定参数是否是固定值
String host = downLoadRepository.getSourceUrl();
int port = Integer.parseInt(sftpPort);
String username = downLoadRepository.getSourceUsername();
String password = downLoadRepository.getSourceUrl();
BcmSFTPUtils sftpUtils = new BcmSFTPUtils(host, port, username, password);
FileConvertConstant.sftp = sftpUtils;
executeConvert.excute(downLoadRepository);
}
}
}
}
}
最终结果证明确实是因为这个原因。
结论:
如果在一个类中使用了@Autowired注入某些实例,那么此类也需要使用@Autowired注入。
原因:
自己new的对象脱离了spring的管理(不在ioc容器中),spring在初始化对象的时候会根据@Autowired进行依赖注入,所以不会为null;而自己new的对象,依赖的这些对象只是被解析为单纯的属性,而不是实例化对象,所以为null。