brandizzi
brandizzi

Reputation: 27100

How to autowire an implementation in an injection point whose type is an interface

Using Spring MVC, I have this Controller class:

@Controller
public class LoginController {
    @Autowired
    private LoginService loginService;
    // more code and a setter to loginService
}

LoginService is an interface, whose only implementation is LoginServiceImpl:

public class LoginServiceImpl implements LoginService {
    //
}

My project-name-servlet.xml file is this one:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">   
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/" />
        <property name="suffix" value=".jsp" />
    </bean>
    <bean id="loginService" class="my.example.service.impl.LoginServiceImpl" />
    <bean class="my.example.controller.LoginController" />
</beans>

The problem is, loginService is not injected into the controller. If I specify the injection in the XML file as below, it works:

    <bean id="loginService"
        class="may.example.service.impl.LoginServiceImpl" />
    <bean class="my.example.controller.LoginController">
        <property name="loginService" ref="loginService"></property>
    </bean>

Why does this happen? Shouldn't the only implementing bean be injected in an interface-typed injection point?

Upvotes: 1

Views: 1347

Answers (2)

brandizzi
brandizzi

Reputation: 27100

A solution that worked to me was to define the autowire type as byType:

    <bean id="loginService"
        class="my.example.service.impl.LoginServiceImpl"
            autowire="byType" />
    <bean class="my.example.controller.LoginController"
            autowire="byType" />

Also, I removed the @Autowired annotations.

Upvotes: 0

Biju Kunjummen
Biju Kunjummen

Reputation: 49935

You have to add a AutowiredAnnotationBeanPostProcessor for the Autowiring to work - It is byType by default, so you don't have to do anything explicit to inject your loginService into your LoginController. Like the link says, you can put a <context:annotation-config/> or <context:component-scan/> to automatically register a AutowiredAnnotationBeanPostProcessor.

Upvotes: 1

Related Questions