在运行该应用程序时,我的spring MVC程序中的服务类仍然为空。这两个类都是@Service,并且在控制器类中具有@Autowired,但仍为null。我浏览了几天,发现的原因只有两个,我认为这都不是我的情况。
Spring Boot应用试图创建Discord机器人,自动装配无法在控制器或Junit测试中运行(执行时为NPE,调试时变量显示为空)。
驱动程序类:
package com.deth;
//imports
@SpringBootApplication
public class DethBotApplication {
private static Logger logger = Logger.getLogger(DethBotApplication.class);
@Autowired
private static BotCommandListener botListener;
public static void main(String[] args) {
SpringApplication.run(DethBotApplication.class, args);
try {
JDA jda = new JDABuilder(AccountType.BOT)
.setToken(TOKEN)
//.addEventListener(command controller)
.addEventListener(botListener)
.build(); //starts listening in discord server.
相关控制器代码:
package com.deth.controller;
//imports
@Component
public class BotCommandListener extends ListenerAdapter {
private static Logger logger = Logger.getLogger(BotCommandListener.class);
@Autowired
@Qualifier("raidAdminService")
private RaidAdminService raidAdminService;
@Autowired
private RaidRosterServiceImpl raidRosterService;
@Autowired
private RaidAttendanceService raidAttendanceService;
@Override
public void onMessageReceived(MessageReceivedEvent event) {
JDA jda = event.getJDA();
String msg = event.getMessage().getContentDisplay();
if(msg.startsWith("!")) {
String command = "";
if(!msg.contains(" ")) {
command = msg;
} else {
command = msg.subSequence(0, msg.indexOf(" ")).toString();
logger.trace("possible command: " + command);
}
try {
switch (command) {
//raid leader commands
case "!open":
raidAdminService.createRaid(event); //NPE here
logger.trace("!open detected");
break;
raidAdminService:
package com.deth.service;
//imports
@Service("raidAdminService")
public class RaidAdminServiceImpl extends CommandInfoService implements RaidAdminService {
String intRegex = "[0-9]+";
@Override
public void createRaid(MessageReceivedEvent event) {
// TODO Auto-generated method stub
包装结构:
程序启动并运行时,在不和谐服务器中发送“!open”,正确命中switch语句并尝试调用createRaid方法,但是RaidAdminService并未自动装配,因此将其调用为null。
答案 0 :(得分:1)
我认为问题出在您的DethBotApplication类中。您不能在那里自动接线。主类需要首先执行。之后,该应用程序将查找@ Componet,@ Service,@ Controller ...批注。下面的代码可能会解决您的问题。
package com.deth;
//imports
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class DethBotApplication extends SpringBootServletInitializer {
private static Logger logger = Logger.getLogger(DethBotApplication.class);
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DethBotApplication.class, args);
BotCommandListener botListener = context.getBean(BotCommandListener.class);
try {
JDA jda = new JDABuilder(AccountType.BOT)
.setToken(TOKEN)
//.addEventListener(command controller)
.addEventListener(botListener)
.build(); //starts listening in discord server.
答案 1 :(得分:0)
您手动实例化了该对象,因此Spring不了解该bean。这就是为什么您的@Autowired字段为null的原因。
Spring Boot必须首先加载主类,然后再通过这些类继续注入注入的Bean。
答案 2 :(得分:0)
扩展ApplicationRunner或CommandLineRunner类
package com.deth;
//imports
@SpringBootApplication
@Component
public class DethBotApplication implements CommandLineRunner {
private static Logger logger = Logger.getLogger(DethBotApplication.class);
@Autowired
private /*static*/ BotCommandListener botListener; // i remove "static" here
public static void main(String[] args) {
SpringApplication.run(DethBotApplication.class, args);
}
@Override
public void run(String args) {
try {
JDA jda = new JDABuilder(AccountType.BOT)
.setToken(TOKEN)
//.addEventListener(command controller)
.addEventListener(botListener)
.build(); //starts listening in discord server.
...
这里的关键是(正如其他答案所指出的)@Autowired仅在它是@Component而不是“静态”时才起作用。
答案 3 :(得分:0)
看看:
@Autowired
private static BotCommandListener botListener;
public static void main(String[] args) {
SpringApplication.run(DethBotApplication.class, args);
try {
JDA jda = new JDABuilder(AccountType.BOT)
.setToken(TOKEN)
.addEventListener(botListener)
//...
}
您为@Autowired
注释了一个静态字段,而Spring并未在静态字段中注入bean(而仅在实例字段中)。
您的问题确实非常普遍:您想在Spring Boot应用程序类的main()中执行某些依赖于某些bean的任务。
正确的方法是使用@PostConstruct
批注。一旦在当前bean上执行依赖项注入,便会(自动)执行带有此方法注释的方法:此处为Spring Boot Application。
它会给出:
@Autowired
private BotCommandListener botListener;
@PostConstruct
public void init(){
JDA jda = new JDABuilder(AccountType.BOT)
.setToken(TOKEN)
.addEventListener(botListener)
.build();
// ...
}