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

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

问题描述:

我遇到组件自动装配的问题。如何在避免使用null @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. 
    */ 

} 

我能做些什么,以正确自动装配组件?

感谢。

+0

创建一个单例MyHandlerImpl bean并将ServletOutputStream传递给它的handle句柄。或者在每个请求上创建自己的'MyHandlerImpl'实例,并将'MyComponentToAutowired' bean传递给它的'handle'方法。 –

您需要使用@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传递给句柄方法并将其注入到控制器。

@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是无状态的。

+0

要自动装配的组件是@RepositoryRestResource。 –