2012-10-12 1 views
6

Мне нужна помощь в понимании концепции за @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> 
+0

ли 'MyPojo' экземпляр к весне? –

+0

Я ничего не сделал для 'MyController' в config.xml, поэтому я не делал этого для' MyPojo'. Что мне делать? – birdy

+0

Можете ли вы разместить свою конфигурацию Spring? –

ответ

12

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

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

В вашем случае объект службы и контроллера управляется весной, но ваш класс POJO не управляется весной, поэтому не производит ожидаемого вами поведения.

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

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

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

+0

Это имеет смысл. Я могу использовать '@ Repository' вместо' @ Service'. В моем pojo я хочу сделать некоторые запросы к базе данных. Именно поэтому я хочу использовать 'myService' в моем POJO. Пожалуйста, дайте мне знать, если есть чтобы сделать это? Все, что я хочу сделать из моего POJO, запускает некоторые запросы к DB – birdy

+0

Как создается экземпляр объекта POJO? –

+0

контроллер просто создает экземпляр pojo следующим образом: 'MyPojo p = new MyPojo(); p.testFromPojo(); ' – birdy

-1

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

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

Я проверил это. Он сканирует все пакеты. – birdy

2

Включите эту опцию в файл applicationContext.xml

<context:annotation-config /> 
5

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

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

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

+0

Итак, я должен аннотировать мое POJO с помощью '@ Service' или' @ Repository' или '@ Controller'? – birdy

+0

Я бы предпочел добавить аннотацию, а не определить ее в xml – birdy

+0

«Аннотирование ваших классов предотвращает управление каждым классом в пакете Spring, что не всегда желательно». действительно? поэтому в пакете может быть аннотирован только один класс? – birdy