Java 如何从实例初始值设定项块调用注入的bean方法

Java 如何从实例初始值设定项块调用注入的bean方法,java,spring,spring-mvc,Java,Spring,Spring Mvc,我正在使用Spring和SpringMvc,我想在某个控制器中调用一个服务的方法,并且两者都是 由Spring管理。当我尝试这样做时,我得到了NullPointerException,但我发现在调用此方法之前,服务的构造函数确实被调用了。 我想这个服务可能是在Spring中添加的,但是这个控制器中的属性还没有设置 我如何从SpringContext获取它 我的代码如下: @Controller @RequestMapping("/test") public class SomeCont

我正在使用Spring和SpringMvc,我想在某个控制器中调用一个服务的方法,并且两者都是 由Spring管理。当我尝试这样做时,我得到了NullPointerException,但我发现在调用此方法之前,服务的构造函数确实被调用了。 我想这个服务可能是在Spring中添加的,但是这个控制器中的属性还没有设置

我如何从SpringContext获取它

我的代码如下:

 @Controller 
 @RequestMapping("/test") 
 public class SomeController {

     @Resource
     private SomeService someService;

     {
         someService.serviceMethod();
         //And something more
     }

     @RequestMapping("/someMethod")
     private void controllerMethod(){

     } 
}

您正试图从初始值设定项块调用spring注入服务。您用@resource注释的资源尚未被spring注入控制器!这就是为什么会出现NullPointerException 创建一个单独的函数,改为使用@PostConstruct注释

@Controller 
@RequestMapping("/test") 
public class SomeController {

    @Resource
    private SomeService someService;

    @PostConstruct
    public void postConstruct(){
        someService.serviceMethod();
    }
}

该“postConstruct”方法将在创建bean(即控制器)并将所有依赖项(包括SomeService)注入bean之后调用。当然,它满足了您只需调用一次的要求。

您的具体问题与Java处理的方式有关:

Java编译器将初始值设定项块复制到每个构造函数中。因此,这种方法可以用于在多个构造函数之间共享一块代码

如果您想坚持使用初始值设定项块,您可以通过向控制器添加构造函数并向其中注入服务来解决此问题:

@Autowired
public SomeController(SomeService someService) {
  this.someService = someService;
}
或者,您可以删除初始值设定项块并添加带注释的设置方法

@PostConstruct
public void setupSomeController(){
    someService.serviceMethod();
}

尝试以下操作:添加属性:@Autowired SomeService SomeService;在controllerMethod:someService.serviceMethod()中,我知道如果我将“someService.serviceMethod();”放在controllerMethod中,它会起作用。但我希望这些代码只运行一次,而不是每次调用此控制器的方法时都运行@是@PostConstruct注释吗?非常感谢。很好的解决方案@SimoThank你!这正是我想要的。谢谢你完美的回答!