Pregunta

Tengo algunos problemas wth Autowire anotación. Mi aplicación es similar al siguiente:

Aquí es controlador:

@Controller
public class MyController {
    @Autowired
    @Qualifier("someService")
    private SomeService someService;

    ....
}

Es una capa de servicio:

public interface SomeService {
    ...
}

@Service
public class SomeServiceImpl implements SomeService{    
    @Autowired
    @Qualifier("myDAO")
    private MyDAO myDAO;

    ....
}

Y capa DAO:

public interface MyDAO{
    ....        
}

@Repository
public class JDBCDAOImpl implements MyDAO {    
    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;    
    ....
}

Este es un archivo app-service.xml:

....
<bean id="propertyConfigurer"
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
      p:location="/WEB-INF/jdbc.properties" />

<bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource"
      p:driverClassName="${jdbc.driverClassName}"
      p:url="${jdbc.url}"
      p:username="${jdbc.username}"
      p:password="${jdbc.password}"/>

<bean id="SomeService" class="com.service.SomeServiceImpl" />    
<bean id="myDAO" class="com.db.JDBCDAOImpl" />    

Así que ... Cuando estoy lanzando una aplicación Web, myController Autowires correctamente (el campo someService correctamente inyectado por objeto de clase SomeServiceImpl), pero myDAO FEILD de someService tiene valor nulo (no inyectada correctamente).

Podría usted ayudarme a encontrar un problema?

P.S. Es interesante, pero cuando estoy cambiando un "bean id" de myDAO a algún otro (por ejemplo myDAO2), el sistema me da un error, que la inyección no se podía hacer, porque frijol myDAO no existe. Por lo tanto, la primavera de administrar la inyección, pero donde es? Y por qué no se funciona correctamente?

¿Fue útil?

Solución

I encontró la solución. Como dijo Javi (gracias mucho por ti, Javi), que tienen que DAO anotar y clases de capa de servicio con @Repository y anotación @Service. Ahora he tratado de escribir así:

@Service("someService")
public class SomeServiceImpl implements SomeService{    
    @Autowired
    @Qualifier("myDAO")
    private MyDAO myDAO;

    ....
}

y

@Repository("myDAO")
    public class JDBCDAOImpl implements MyDAO {    
    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;    
    ....
}

y todo funciona bien !!!

Pero todavía no encontró una respuesta para esto quesion: si la aplicación será más complejo, y tendrá una estructura más compleja, donde @Repositore y anotación @Service no se prefieren para algunas clases, cómo inyectar correctamente frijoles, que localizaron en la parte baja niveles (en unos campos de clases, o en un campo de campos de clases) (con anotación @Autowire, por supuesto)?

Otros consejos

Creo que necesita <context:annotation-config />.

Puede utilizar

<context:component-scan base-package="PATH OF THE BASE PACKAGE"/>  

entrada en el archivo .xml de configuración. Esta entrada escaneará / leer todo el tipo y anotaciones declarado de las clases de Java.

Los puntos importantes:

  1. A veces, @Component puede lleva a un problema en el que se podría decir sin constructor predeterminado encontrados. La clase que se define como una anotación de @Component, debe tener un constructor por defecto.
  2. Supongamos, hemos aplicado anotación @Autowired en el campo que es una referencia de clase definida por el usuario. Ahora bien, si aplicamos también @Component a esa clase, entonces siempre se inicia con nula. Por lo tanto, un campo con @Autowired no debería tener @Component en su definición de clase.
  3. Por defecto @Autowired es byType.

Dirección de frijol se autowired en la clase del estudiante. Veamos lo que sucede si aplicamos @Component en Address.java.

CollegeApp.java:

package com.myTest
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.bean.Address;
import com.bean.Student;
//Component scanning will for only those classes
//which is defined as @Component. But, all the class should not use
//@Component always even if the class is enabled with auto
//component scanning, specially the class which is Autowired
//Or which is a property of another class 
@Configuration
@ComponentScan(basePackages={"com.bean"})
public class CollegeApp {
    @Bean
    public Address getAddress(){
        return new Address("Elgin street");
}
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(CollegeApp.class);
        Student student=context.getBean(Student.class);
        System.out.println(student.toString());
        context.close();
    }
}

Queremos calle Elgin a ser autowired con la dirección del Estudiante.

Address.java:

package com.bean;
import org.springframework.stereotype.Component;
@Component
public class Address {
    private String street;
    public Address()
    {
    }
    public Address(String theStreet)
    {
        street=theStreet;
    }
    public String toString()
    {
        return (" Address:"+street);
    }
}

Student.java:

package com.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Student {
    private String name;
    private int age;
    private Address address;
    public Student()
    {
    }
    public Student(String theName,int theAge)
    {
        name=theName;age=theAge;
    }
    @Autowired
    public void setAddress(Address address) {
        this.address = address;
    }
    public String toString()
    {
        return ("Name:"+name+" Age:"+age+ " "+address);
    }
}

Salida: - Nombre:. Nula Edad: 0 Dirección: null // Dirección no Autowired aquí

Para resolver el problema, sólo cambian el Address.java como a continuación:

Address.java:

package com.bean;
public class Address {
    private String street;
    public Address(String theStreet)
    {
        street=theStreet;
    }
    public String toString()
    {
        return (" Address:"+street);
    }
}

Salida: - Nombre: null Edad: 0 Dirección: Calle Elgin

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- Specifying base package of the Components like Controller, Service, 
        DAO -->
    <context:component-scan base-package="com.jwt" />

    <!-- Getting Database properties -->
    <context:property-placeholder location="classpath:application.properties" />

    <!-- DataSource -->
    <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        id="dataSource">
        <property name="driverClassName" value="${database.driver}"></property>
        <property name="url" value="${database.url}"></property>
        <property name="username" value="${database.user}"></property>
        <property name="password" value="${database.password}"></property>
    </bean>

    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            </props>
        </property>
    </bean>

</beans>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top