Search code examples
springautowiredapplicationcontext

NullPointerException with @Autowired in Spring


I try to use Spring framework with @Autowired annotation to get a Service class.

Here my class (this class is called by a WebSocketServlet) which need to use the Service (I get NullPointerException on call of it):

public class SignupWebSocketConnection extends MessageInbound {

    private static final Logger log = LoggerFactory.getLogger(SignupWebSocketConnection.class);

    @Autowired
    private UserService userService;

    @Override
    protected void onOpen(WsOutbound outbound) {
        log.info("Connection done");
    }

    @Override
    protected void onClose(int status) {
        log.info("Connection close");
    }

    @Override
    protected void onBinaryMessage(ByteBuffer byteBuffer) throws IOException {
        log.warn("Binary message are not supported");
        throw new UnsupportedOperationException("Binary message are not supported");
    }

    @Override
    protected void onTextMessage(CharBuffer charBuffer) throws IOException {

        User userTest = new User("log", "pass", "ema");
        userService.create(userTest);

    }
}

Here my web.xml :

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

Here my ApplicationContext.xml :

<bean id="userService" class="service.UserService">

If I try to use the Service in the test package (I using maven) with explicit call of the ApplicationContext-test.xml, it's working fine... The ApplicationContext.xml and ApplicationContext-test.xml are same (just param to database changes)

Thank's a lot to all of you :D

EDIT :

I deplace my applicationContext.xml in ressources folder and create a class to test :

   public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) ctx.getBean("userService");
        User user = new User("log","pas","emai");
        userService.create(user);
    }

I get NullPointerException also when calling userService.create() ....


Solution

  • When not using aspects/code weaving, you need to get your beans from the Springs' ApplicationContext (if the object is already created by Spring, all the @Autowired fields will get set), as Spring is not aware of you creating objects with new. The usual way of writing web-applications with Spring is using DispatcherServlet and Controllers, not Servlets, for a quick tutorial see for example here. The reasoning behind this is that Spring will take care of creating all the @Controller/@Service/etc-annotated classes, autowire the marked fields without fuss, handle delegating the requests to correct controller methods and more.

    However, it is possible to fetch the application context and the beans in Servlets also, but the code is much less clean, not so easily tested and probably becomes a nightmare to maintain in the long run. For example:

       WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
       MyBeanFromSpring myBean =(MyBeanFromSpring)springContext.getBean("myBeanFromSpring");
       //Do whatever with myBean...