@Autowired и @Service работают от контроллера, но не из другого пакета

мне нужна помощь в понимании концепции @Autowired и @Service. У меня есть DAO, определенный с @Service и контроллер с @Autowired и все кажется прекрасным, однако я использую то же самое @Autowired в другом классе, то это не работает.

пример:

сервис

@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");
    }
}

контроллер

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";
  }
}

выше все работает нормально. Однако, если я хочу использовать MyService в POJO тогда это просто не работает. Пример:

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>

5 ответов


это потому,что ваш класс POJO не управляется контейнером spring.

@Autowire аннотация будет работать только с теми объектами, которые управляются spring (т. е. создаются контейнером spring).

в вашем случае объект service и controller управляется spring, но ваш класс POJO не управляется spring, поэтому @Autowire не производит поведение, ожидаемое вами.

еще одна проблема, которую я заметил, вы используете @Service аннотация в слое DAO, когда весна имеет @Repository аннотация, специально созданная для этой цели.

также не желательно позволять spring управлять классами POJO, так как обычно это будут элементы хранения данных, которые должны быть созданы вне контейнера.

можете ли вы сказать нам, какова цель класса POJO и почему service экземпляр используется в нем?


при использовании сканирования classpath вы должны сообщить Spring, какие классы для управления. Это делается с помощью @Service аннотация и ее отношения (@Controller, @Repository и т. д.).

если вы выберите не чтобы аннотировать ваш bean, вы должны явно объявить его в своей конфигурации, так же, как вы сделали с dataSource и jdbcTemplate.

аннотирование ваших классов означает, что только те классы в пакете управляются Spring; что позволяет сканировать пакет без необходимости управлять все классы в этом пакете.


включите это в applicationContext.xml-файл

<context:annotation-config />

вы можете реализовать это, чтобы использовать spring-управляемые бобы в вашем классе POJO.

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


проверьте сканирование компонентов контекста в файле конфигурации

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