如何在接口实现中自动装配组件,避免null @Autowired?

时间:2016-05-23 16:14:05

标签: java spring autowired

我遇到组件自动装配问题。

我的实现包括Controller,Controller使用的接口和实现thagt接口的Component。 我想在实现中自动装配另一个组件。

这是控制器:

@Controller
public class MyController {

    @RequestMapping(path = "/myPath/{subpath}", method = RequestMethod.GET)
    public void myMethod(@PathVariable("subpath") String subpath, HttpServletResponse response){        
        try{
            MyHandler handler = new MyHandlerImpl(response.getOutputStream());
            handler.handle();       
        } catch (Exception e) {

        }       
    }   
}

这是界面:

public interface MyHandler {

    public void handle();

}

这就是实施:

// tried all: @Component, @Service, @Repository, @Configurable
public class MyHandlerImpl implements MyHandler {

    @Autowired
    MyComponentToAutowired myComponentToAutowired; // <= this is NULL

    public MyHandlerImpl (ServletOutputStream output) {
        this.output = output;
    }

    private OutputStream output;

    public void handle() {
        myComponentToAutowired.theMethod(); // <- NullPointerException at this point
        // ...
    }

    /*
        If I don't create a default constructor, Spring crash at the start because it not finds the default constructor with no-args.
    */

}

如何正确自动装配组件?

感谢。

1 个答案:

答案 0 :(得分:0)

您需要使用@Component注释MyComponentToAutowired实现。你的MyComponentToAutowired实现在哪里?

这将在Spring上下文中创建一个MyComponentToAutowired实例,该实例将连接到MyHandlerImpl实例。

问题是你正在实例化一个MyHandlerImpl对象而不是使用IoC容器(Spring)创建的那个,那是注入了MyComponentToAutowired的那个。

为了使用有线MyHandlerImpl,您应该

@Component
public class MyHandlerImpl implements MyHandler {

@Controller
public class MyController {

@Autowired
MyHandlerImpl myHandler;

@RequestMapping(path = "/myPath/{subpath}", method = RequestMethod.GET)
public void myMethod(@PathVariable("subpath") String subpath, HttpServletResponse response){        
    try{
        myHandler.setStream(response.getOutputStream());
        handler.handle();       
    } catch (Exception e) {

    }       
  }   
}

但是所有请求都将共享相同的MyHandlerImpl实例,这不是你想要的。

您可以将MyComponentToAutowired传递给handle方法并将其注入控制器。

@Controller
public class MyController {

@Autowired
MyComponentToAutowired myComponent;

@RequestMapping(path = "/myPath/{subpath}", method = RequestMethod.GET)
public void myMethod(@PathVariable("subpath") String subpath, HttpServletResponse response){        
    try{
        MyHandler handler = new MyHandlerImpl(response.getOutputStream());
        handler.handle(myComponent);       
    } catch (Exception e) {

    }       
  }   
}

我认为你的MyComponentToAutowired是无状态的。