@Autowired and @Service working from controller but not from a different package

31,385

Solution 1

It is because your POJO class is not managed by spring container.

@Autowire annotation will work only those objects which are managed by spring (ie created by the spring container).

In your case the service and controller object are managed by spring, but your POJO class is not managed by spring, that is why the @Autowire is not producing the behavior expected by you.

Another problem I noticed is, you are using the @Service annotation in the DAO layer when spring has the @Repository annotation specifically created for this purpose.

Also it is not desirable to allow spring to manage the POJO classes since normally it will be data storage elements which has to be created outside the container.

Solution 2

When using classpath scanning, you have to communicate to Spring which classes to manage. This is done using the @Service annotation, and its relations (@Controller, @Repository, etc).

If you choose not to annotate your bean, you must explicitly declare it in your config, just like you did with dataSource and jdbcTemplate.

Annotating your classes means only those classes in the package are managed by Spring; which allows you to scan a package without having to manage all classes in that package.

Solution 3

Include this in applicationContext.xml file

<context:annotation-config />
Share:
31,385
birdy
Author by

birdy

Updated on January 16, 2022

Comments

  • birdy
    birdy over 2 years

    I need help understanding the concept behind @Autowired and @Service. I have a DAO defined with @Service and controller with @Autowired and everything seems fine, however, I use the same @Autowired in a different class then it does not work.

    Example:

    Service

    @Service
    public class MyService {
        private JdbcTemplate jdbcTemplate;
    
        @Autowired
        public void setDataSource (DataSource myDataSource) {
            this.jdbcTemplate = new JdbcTemplate(myDataSource);
        } 
    
        public void testUpdate(){
                jdbcTemplate.update("some query");
        }
    }
    

    Controller

    package com.springtest.mywork.controller;
    
    @Controller
    @RequestMapping(value = "/test.html")
    public class MyController
    {
      @Autowired
      MyService myService;
    
      @RequestMapping(method = RequestMethod.GET)
      public String test(Model model)
      {
        systemsService.testUpdate();
        return "view/test";
      }
    }
    

    The above all works fine. However, If I want to use MyService in a POJO then it just doesn't work. Example:

    package com.springtest.mywork.pojos;
    public class MyPojo {
    
        @Autowired
        MyService myService;
    
        public void testFromPojo () {
            myService.someDataAccessMethod(); //myService is still null
        }
    }
    

    Spring Config:

    <beans>
        <mvc:annotation-driven />
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/views/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
        <context:component-scan base-package="com.springtest.mywork" />
        <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver" />
            <property name="url" value="jdbc:mysql://127.0.0.1:3306/mydb" />
            <property name="username" value="hello" />
            <property name="password" value="what" />
        </bean>
    
        <bean name="jdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
            <constructor-arg ref="dataSource"/>
        </bean>
     </beans>
    
  • birdy
    birdy over 11 years
    I've checked this. It is scanning all the packages.
  • birdy
    birdy over 11 years
    So I should annotate my POJO with @Service or @Repository or @Controller?
  • birdy
    birdy over 11 years
    I would prefer to add annotation rather than define it in the xml
  • birdy
    birdy over 11 years
    "Annotating your classes prevents every class in a package being managed by Spring; something that isn't often desirable." really? so in a package only one class can be annotated?
  • David Grant
    David Grant over 11 years
    @Service is the most non-specific, so that's what I'd use.
  • David Grant
    David Grant over 11 years
    @birdy I mean, by annotating, you choose which classes to be managed.
  • birdy
    birdy over 11 years
    even with @Service it is coming to NULL :(
  • David Grant
    David Grant over 11 years
    And it's in the same package?
  • birdy
    birdy over 11 years
    no. Its in a different package. Controller is in com.springtest.mywork.controller and pojo is in com.springtest.mywork.mypojo . In the spring config I have <context:component-scan base-package="com.springtest.mywork" /> so I'm assuming both sub packages controller and mypojo should be scanned...?
  • David Grant
    David Grant over 11 years
    Try adding <context:annotation-config> (as @Pradeep mentions below)
  • birdy
    birdy over 11 years
    still same. I give up. perhaps i need to step away
  • Arun P Johny
    Arun P Johny over 11 years
  • Maciej Lach
    Maciej Lach over 8 years
    Please avoid link only answers.