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

旧城冷巷雨未停 提交于 2019-12-03 17:15:48

问题


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>

回答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.

Can you tell us what is the purpose of the POJO class and why the service instance is used in it?




回答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.




回答3:


Include this in applicationContext.xml file

<context:annotation-config />



回答4:


You can implement this to use spring-managed beans in your POJO class.

http://www.javacodegeeks.com/2015/03/using-spring-managed-bean-in-non-managed-object.html




回答5:


check your context component scan in your configuration file

<context:component-scan base-package="<your_package>" />


来源:https://stackoverflow.com/questions/12862203/autowired-and-service-working-from-controller-but-not-from-a-different-package

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!