Spring @Autowired не работает - PullRequest
       35

Spring @Autowired не работает

9 голосов
/ 26 ноября 2010

У меня проблемы с аннотацией autowire. Мое приложение выглядит так:

Вот контроллер:

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

    ....
}

Это сервисный слой:

public interface SomeService {
    ...
}

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

    ....
}

И слой DAO:

public interface MyDAO{
    ....        
}

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

Это файл 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" />    

Итак ... Когда я запускаю веб-приложение, MyController Autowires корректно (поле someService правильно введено объектом класса SomeServiceImpl), но в myDAO поле someService имеет нулевое значение (неправильно введено).

Не могли бы вы помочь мне найти проблему?

P.S. Интересно, но когда я меняю «идентификатор компонента» с myDAO на какой-то другой (например, myDAO2), система выдает мне ошибку, из-за которой невозможно выполнить инъекцию, поскольку bean myDAO не существует. Итак, Spring сделайте укол, но где он? И почему это не работает правильно?

Ответы [ 5 ]

10 голосов
/ 26 ноября 2010

Я нашел решение.Как сказал Javi (большое спасибо за вас, Javi), я должен аннотировать классы DAO и Service layer аннотациями @Repository и @Service.Теперь я попытался написать так:

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

    ....
}

и

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

и все работает отлично !!!

Но я до сих пор не нашел ответа наэтот вопрос: если приложение будет более сложным и будет иметь более сложную структуру, где аннотации @Repositore и @Service не являются предпочтительными для некоторых классов, как правильно вводить bean-компоненты, расположенные на более низких уровнях (в полях классовили в поле полей классов) (с аннотацией @Autowire, конечно)?

4 голосов
/ 26 ноября 2010

Я думаю, вам нужно <context:annotation-config />.

2 голосов
/ 23 сентября 2013

Вы можете использовать запись

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

в файле конфигурации XML.Эта запись будет сканировать / читать все указанные типы и аннотации из классов Java.

0 голосов
/ 08 августа 2018

Важные моменты:

  1. Иногда @Component может привести к проблеме, когда он может сказать, что конструктор по умолчанию не найден. Класс, который определяется как аннотация @Component, должен иметь конструктор по умолчанию.
  2. Предположим, мы применили аннотацию @Autowired к полю, которое является пользовательской ссылкой на класс. Теперь, если мы также применим @Component к этому классу, он всегда будет инициализирован нулем. Таким образом, поле с @Autowired не должно иметь @Component в своем определении класса.
  3. По умолчанию @Autowired имеет тип ТИПА.

Адресный компонент автоматически подключается в классе Student. Давайте посмотрим, что произойдет, если мы применим @Component к 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();
    }
}

Мы хотим, чтобы улица Элгина была автоматически подключена с адресом студента.

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

Вывод: - Имя: ноль Возраст: 0 Адрес: ноль // Адрес не подключен автоматически.

Для решения проблемы измените только Address.java, как показано ниже:

Address.java:

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

Выход: - Имя: ноль Возраст: 0 Адрес: улица Эльгина

0 голосов
/ 13 апреля 2018
<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>
...