Spring MVC中@Autowired注入PlayersDAO为null问题求助
解决Spring MVC中new对象导致@Autowired注入失败的问题
你猜的没错,用new Team()创建实例就是PlayersDAO为null的核心原因。Spring的依赖注入只对容器管理的Bean生效,手动new出来的对象不在Spring容器的管控范围内,@Autowired注解根本不会被处理,PlayersDAO自然是null。
下面给你几种适配不同场景的解决方案:
方案1:让Spring管理Team实例(无状态场景优先用)
如果Team不需要每个请求都生成新实例(比如只是封装业务逻辑,没有请求专属的状态数据),直接给Team加上Spring的Bean注解,然后在Controller里注入Team而非new。
示例代码:
// Team类添加@Component(或@Service,根据业务分层选) @Component public class Team { @Autowired private PlayersDAO playersDAO; public void addPlayer(Player player) { if(playersDAO != null) { playersDAO.getPlayers().add(player); } } } // TeamsController里注入Team @Controller public class TeamsController { @Autowired private Team team; @PostMapping("/addPlayer") public String handleAddPlayer(Player player) { team.addPlayer(player); return "redirect:/players"; } }
方案2:生成多实例Team(有状态场景用)
如果确实需要每次请求都创建新的Team实例(比如每个Team有专属的名称、属性等请求级状态),给Team加上@Scope("prototype"),让Spring每次获取Bean时都生成新实例,再通过容器或工厂获取。
示例代码:
// Team类标注为原型作用域 @Component @Scope("prototype") public class Team { @Autowired private PlayersDAO playersDAO; private String teamName; // 请求专属的状态属性 // getter/setter public void addPlayer(Player player) { if(playersDAO != null) { playersDAO.getPlayers().add(player); } } } // 方式1:通过ApplicationContext获取新实例 @Controller public class TeamsController { @Autowired private ApplicationContext context; @PostMapping("/addPlayer") public String handleAddPlayer(Player player, @RequestParam String teamName) { Team team = context.getBean(Team.class); team.setTeamName(teamName); team.addPlayer(player); return "redirect:/players"; } } // 方式2:用ObjectFactory获取新实例(更解耦) @Controller public class TeamsController { @Autowired private ObjectFactory<Team> teamFactory; @PostMapping("/addPlayer") public String handleAddPlayer(Player player) { Team team = teamFactory.getObject(); team.addPlayer(player); return "redirect:/players"; } }
方案3:手动注入PlayersDAO(兜底方案,不推荐)
如果不想让Spring管理Team,给Team加个带参构造器,在Controller里先注入PlayersDAO,再手动传给new出来的Team。
示例代码:
// Team类添加带参构造器 public class Team { private PlayersDAO playersDAO; public Team(PlayersDAO playersDAO) { this.playersDAO = playersDAO; } public void addPlayer(Player player) { if(playersDAO != null) { playersDAO.getPlayers().add(player); } } } // TeamsController里手动传递PlayersDAO @Controller public class TeamsController { @Autowired private PlayersDAO playersDAO; @PostMapping("/addPlayer") public String handleAddPlayer(Player player) { Team team = new Team(playersDAO); team.addPlayer(player); return "redirect:/players"; } }
优先选方案1或2,这符合Spring的设计思路,能减少代码耦合;方案3是实在没办法时的兜底手段,尽量少用。
内容的提问来源于stack exchange,提问作者Doszhan Turar
相关产品推荐
相关产品推荐

