Spring依赖注入不起作用

时间:2017-06-15 17:51:17

标签: java spring dependency-injection autowired

我的独立Java应用程序出现问题。问题是我试图自动装配我的服务和我的DAO,但是当我从UI调用服务方法时,我得到NullPointerException,因为依赖注入不能正常工作。我尝试过很多东西,其中很多都来自类似的问题,但问题仍然存在。我使用的是Spring 4.0.6.RELEASE和Hibernate 4.3.11.Final。这是我的代码:

1 - 调用服务:

public class LoginView {

    @Autowired
    private UsuarioService usuarioService;
    ...
    ...
    JButton btnAutenticarse = new JButton("Autenticar");
    btnAutenticarse.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            try {
                Usuario usuario = usuarioService.login(textField.getText(),
                        String.valueOf(passwordField.getPassword()), false); // NullPointerException

            } catch (InstanceNotFoundException e1) {
     ...

2 - 服务定义:

@Service("usuarioService")
public class UsuarioServiceImpl implements UsuarioService {

    @Autowired
    private UsuarioDao usuarioDao;
    ...

3 - DAO的定义:

@Repository("usuarioDao")
public class UsuarioDaoHibernate extends GenericDaoHibernate <Usuario, Long>
    implements UsuarioDao {
    ...

4 - GenericDAO的定义:

public class GenericDaoHibernate<E, PK extends Serializable> implements
    GenericDao<E, PK> {

@Autowired
private SessionFactory sessionFactory;
....

5 - AppConfig.java

@Configuration
@ComponentScan(basePackages = "org.example.model")
public class AppConfig {

@Bean(name = "usuarioService")
public UsuarioService usuarioService() {
    return new UsuarioServiceImpl();
}

@Bean(name = "usuarioDao")
public UsuarioDao usuarioDao() {
    return new UsuarioDaoHibernate();
}

6 - spring-config.xml

<!-- Enable usage of @Autowired. -->
<context:annotation-config/>

<!-- Enable component scanning for defining beans with annotations. -->
<context:component-scan base-package="org.example.model"/>

<!--  For translating native persistence exceptions to Spring's 
      DataAccessException hierarchy. -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/appdb" />
    <property name="username" value="username" />
    <property name="password" value="password"/>
</bean>

<bean id="dataSourceProxy" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy"
    p:targetDataSource-ref="dataSource"/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan">
        <list>
            <value>org.example.model</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">false</prop>
            <prop key="hibernate.format_sql">false</prop>
        </props>
    </property>       
</bean>

<bean id="transactionManager"  class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="persistenceExceptionTranslationPostProcessor"
    class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

<!-- Enable the configuration of transactional behavior based on
     annotations. -->
<tx:annotation-driven transaction-manager="transactionManager" />

2 个答案:

答案 0 :(得分:1)

Spring只会在Spring托管bean中注入Autowired字段。 AKA如果您使用new LoginView() Spring无法注入依赖项。

public class LoginView {

  @Autowired
  private UsuarioService usuarioService;
}

应该是

@Component
public class LoginView {

  @Autowired
  private UsuarioService usuarioService;
}

如果你不能让Spring管理那个类,你需要以不同的方式设计它。

顺便说一下,我建议你使用构造函数注入而不是字段注入。

我可能会做的是让另一个类成为一个Spring托管bean并执行类似的操作:

@Component
public class InitClass{

  private UsarioService usarioService;

  @Autowired
  public InitClass(UsarioService usarioService){
    this.usarioService = usarioService;
  }         

  @PostConstruct
  public void init(){
    new LoginView(usarioService);
  }         
}

然后这个类将处理你在@PostConstruct中正在进行的所有初始化。可能需要在@PostConstruct中执行此操作,因为在此之前可能无法完全初始化Spring bean。

然而,如果没有看到所有内容的初始化,很难说出最佳策略是什么。

答案 1 :(得分:0)

在应用程序上下文文件中进行显式组件扫描。我确实喜欢这个,它对我有用。

<context:component-scan base-package="com.example" />

您可以在链接here

中查看更多信息