2012-10-12 70 views
6

Necesito ayuda para entender el concepto detrás de @Autowired y @Service. Tengo un DAO definido con @Service y controlador con @Autowired y todo parece estar bien, sin embargo, utilizo el mismo @Autowired en una clase diferente y luego no funciona.@Autowired y @Service trabajando desde el controlador pero no desde un paquete diferente

Ejemplo:

Servicio

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

controlador

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

El encima de todo funciona bien. Sin embargo, si quiero usar MyService en un POJO, simplemente no funciona. Ejemplo:

package com.springtest.mywork.pojos; 
public class MyPojo { 

    @Autowired 
    MyService myService; 

    public void testFromPojo() { 
     myService.someDataAccessMethod(); //myService is still null 
    } 
} 

primavera 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

es 'MyPojo' instanciado por la primavera? –

+0

No he hecho nada para 'MyController' en config.xml, así que tampoco lo hice para' MyPojo'. ¿Qué debería estar haciendo? – birdy

+0

¿Puedes publicar tus configuraciones de Spring? –

Respuesta

12

Es porque su clase POJO no está administrada por contenedor de resorte.

@Autowire anotación solo funcionará aquellos objetos que son gestionados por resorte (es decir, creado por el contenedor de resorte).

En su caso, el objeto de servicio y controlador se gestiona por resorte, pero su clase POJO no está administrada por resorte, por eso el @Autowire no está produciendo el comportamiento esperado por usted.

Otro problema que noté es que está utilizando la anotación @Service en la capa DAO cuando el resorte tiene la anotación @Repository creada específicamente para este propósito.

Tampoco es deseable permitir que el resorte administre las clases de POJO, ya que normalmente serán los elementos de almacenamiento de datos los que deben crearse fuera del contenedor.

¿Puede decirnos cuál es el propósito de la clase POJO y por qué se usa la instancia service?

+0

Eso tiene sentido. Puedo usar '@ Repository' en lugar de' @ Service'. En mi pojo quiero hacer algunas consultas a la base de datos. Es simplemente por eso que quiero usar 'myService' en mi POJO. Por favor, avíseme si hay un ser tter manera de hacer esto? Todo lo que quiero hacer desde mi POJO es ejecutar algunas consultas al DB – birdy

+0

¿Cómo se crea la instancia del objeto POJO? –

+0

el controlador simplemente ejemplifica el pojo como así: 'MyPojo p = new MyPojo(); p.testFromPojo(); ' – birdy

-1

comprobar su exploración componente contexto en el archivo de configuración

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

He comprobado esto. Está escaneando todos los paquetes. – birdy

2

incluir esto en el archivo applicationContext.xml

<context:annotation-config /> 
5

Cuando usando classpa En el escaneo, debes comunicarte a Spring qué clases administrar. Esto se hace usando la anotación @Service y sus relaciones (@Controller, @Repository, etc.).

Si decide no para anotar el bean, debe declarar explícitamente en su configuración, al igual que lo hizo con dataSource y jdbcTemplate.

Anotar sus clases significa que solo las clases en el paquete son administradas por Spring; que le permite escanear un paquete sin tener que administrar todas las clases en ese paquete.

+0

¿Debo anotar mi POJO con '@ Service' o' @ Repository' o '@ Controller'? – birdy

+0

Preferiría agregar una anotación en lugar de definirla en el xml – birdy

+0

"Anotar las clases evita que todas las clases de un paquete sean administradas por Spring, algo que a menudo no es deseable". ¿De Verdad? entonces en un paquete solo una clase puede ser anotada? – birdy

Cuestiones relacionadas