我在使用Spring进行依赖注入时遇到了一个问题,
这是我的服务:
package IntegraLogger.Controller.Service;
//imports
@Component
public class PlcService extends ServiceBase<Plc, Long, PlcRepository> {
@Autowired
public PlcService(PlcRepository repository) {
super(repository);
}
private List<TcpConnection> connections = new ArrayList<>();
public List<TcpConnection> getConnections() {
return connections;
}
public void test() {
System.out.println("works!");
}
}
在这里,我所有的 @Autowired 依赖项都能正常工作!
package IntegraLogger.Enviroment;
//imports
@Component
public class ApplicationStartup implements
ApplicationListener<ApplicationReadyEvent> {
@Autowired
private PlcService plcService;
@Autowired
private ThreadPool pool;
@Autowired
private UserService userService;
@Autowired
private ItagConfigService itagConfigService;
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
//just prepare the enviroment for develop running
startupEnviroment();
}
private void startupEnviroment() {
//TODO this is a temporary enviroment preparation
User user = new User();
user.setName("William Douglas");
user.setEmail("wdouglas@test.com");
user.setPassword("TeSt");
user.setPhoneNumber("1234567890");
userService.save(user);
Plc plc = new Plc();
Plc plc2 = new Plc();
plc.setIp("192.168.0.217");
plc2.setIp("192.168.0.217");
plc.setSlot(0);
plc2.setSlot(0);
plc.setDescription("PLC_Teste01");
plc2.setDescription("PLC_Segundo");
ItagConfig itagConfig1 = new ItagConfig("Bool1", "Tag Booleano de mudança rápida", 1);
ItagConfig itagConfig2 = new ItagConfig("AlarmTest", "PLC 2 - Alarme de Teste", 1);
ItagConfig itagConfig3 = new ItagConfig("wstring", "Palavra lida", 1);
ItagConfig itagConfig4 = new ItagConfig("timmer1.ACC", "Valor acumulado de tempo", 5);
ItagConfig itagConfig5 = new ItagConfig("wdouglas", "valor inteiro eu acho", 2);
ItagConfig itagConfig6 = new ItagConfig("xSecCounter", "Contador em segundos", 2);
ItagConfig itagConfig7 = new ItagConfig("Body1HFlow", "PLC 2 - Variável real aleatória", 5);
itagConfig1.setListener(ListenersIndex.EMAIL);
itagConfig7.setListener(ListenersIndex.PERSIST);
plc.getItagConfigs().add(itagConfig1);
plc2.getItagConfigs().add(itagConfig2);
plc.getItagConfigs().add(itagConfig3);
plc.getItagConfigs().add(itagConfig4);
plc.getItagConfigs().add(itagConfig5);
plc.getItagConfigs().add(itagConfig6);
plc2.getItagConfigs().add(itagConfig7);
itagConfigService.save(itagConfig1);
itagConfigService.save(itagConfig2);
itagConfigService.save(itagConfig3);
itagConfigService.save(itagConfig4);
itagConfigService.save(itagConfig5);
itagConfigService.save(itagConfig6);
itagConfigService.save(itagConfig7);
plcService.save(plc);
plcService.save(plc2);
PlcThread plcThread = new PlcThread(plc);
pool.addPlcThread(plcThread);
System.out.println(plcThread);
Thread thread = new Thread(plcThread, plc.getDescription());
pool.addThread(thread);
thread.start();
PlcThread plcThread2 = new PlcThread(plc2);
pool.addPlcThread(plcThread2);
System.out.println(plcThread2);
Thread thread2 = new Thread(plcThread2, plc2.getDescription());
pool.addThread(thread2);
thread2.start();
}
}
请注意,我启动了新线程,这些线程调用了一些需要访问我的服务的方法,但是这些依赖项为null ...
这里是一个例子:
package IntegraLogger.Enviroment;
//imports
@Component
public class PlcConnection {
@Autowired
private PlcService plcService;
public Connection plcConnect(Plc plc) {
try {
TcpConnection con = new TcpConnection(plc.getIp(), plc.getSlot());
RegisterSession register = new RegisterSession();
con.execute(register);
con.setSession(register.getSession());
System.out.println(plc.getDescription() + " connection is open: " + con.isOpen());
plcService.getConnections().add(con);
return con;
} catch (Exception e) {
System.out.println("Controller " + plc.getDescription() + " - IP: " + plc.getIp() + " not connected");
e.printStackTrace();
return null;
}
}
}
当我启动一个新线程并尝试访问任何@Autowired依赖项时,该对象为null,但是当我在主线程中访问时是可以的。
Spring是否有解决此问题的方法?如果没有,有人知道我该如何解决?
非常感谢!
编辑: 当我创建一个PlcThread时,构造函数将调用plcConnection:
PlcThread plcThread = new PlcThread(plc);
pool.addPlcThread(plcThread);
System.out.println(plcThread);
Thread thread = new Thread(plcThread, plc.getDescription());
pool.addThread(thread);
thread.start();
这是PlcThread类:
package IntegraLogger.Application;
//imports
public class PlcThread implements Runnable, ConnectionFailListener {
private PlcConnection plcConnection = new PlcConnection();
private TagEmail tagEmail = new TagEmail();
private TagPersist tagPersist = new TagPersist();
private TagLogger tagLogger = new TagLogger();
private Plc plc;
private List<Tag> tags = new ArrayList<>();
private Scanner scanner;
private boolean connectionMonitor;
public PlcThread(Plc plc) {
this.plc = plc;
Connection connection = plcConnection.plcConnect(plc); //
this.scanner = new Scanner(connection, 5, this);
this.connectionMonitor = true;
}
public boolean checkConnection() {
EtherNetIP netIP = new EtherNetIP(plc.getIp(), plc.getSlot());
try {
netIP.connectTcp();
netIP.close();
return true;
} catch (Exception e) {
System.out.println("Fail to connect! Device description: '" + plc.getDescription() + "' IP: " + plc.getIp());
e.printStackTrace();
return false;
}
}
public void scan() {
for (ItagConfig itagConfig : plc.getItagConfigs()) {
Tag tag = scanner.add(itagConfig.getTimeUpdate(), itagConfig.getName());
for (ListenersIndex listenersIndex : itagConfig.getListeners()) {
if (listenersIndex.equals(ListenersIndex.EMAIL)) {
tag.addListener(tagEmail);
}
if (listenersIndex.equals(ListenersIndex.LOGGER)) {
tag.addListener(tagLogger);
}
if (listenersIndex.equals(ListenersIndex.PERSIST)) {
tag.addListener(tagPersist);
}
}
this.tags.add(tag);
}
}
@Override
public void run() {
boolean b = true;
System.out.println("Thread " + plc.getDescription() + " has started!");
scan();
while (b) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!checkConnection() || !connectionMonitor) {
b = false;
this.scanner.stop();
}
}
System.out.println("Thread " + plc.getDescription() + " FINISHED");
}
@Override
public void actionFailure(TagList tagList) {
System.out.println("Error try out --------------------------------------------------");
this.connectionMonitor = false;
}
public Plc getPlc() {
return plc;
}
}
此后,所有自动装配对象均有效,它们全部为空... 我认为问题出在上下文上,因为这是一个新线程,但我不确定任何事情...
谢谢