Spring dependency injection not working

自闭症网瘾萝莉.ら 提交于 2021-01-27 19:04:15

问题


I've got a problem in my standalone Java application. The thing is that I'm trying to Autowire both my Services and my DAOs, but I get a NullPointerException when I invoke service methods from the UI since dependency injection is not working properly. I've tried a lot of things, many of them from similar questions, but the problem is still there. I'm using Spring 4.0.6.RELEASE and Hibernate 4.3.11.Final. Here is my code:

1 - Invocation of service:

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 - Definition of service:

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

    @Autowired
    private UsuarioDao usuarioDao;
    ...

3 - Definition of DAO:

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

4 - Definition of 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" />

回答1:


Spring will only inject Autowired fields in Spring managed beans. AKA if you are using new LoginView() Spring cannot inject dependencies.

public class LoginView {

  @Autowired
  private UsuarioService usuarioService;
}

should be

@Component
public class LoginView {

  @Autowired
  private UsuarioService usuarioService;
}

If you can't let Spring manage that class, you'll need to design it a different way.

I'd recommend you use constructor injection instead of field injection, by the way.

What I might do is make another class to be a Spring managed bean and do something like this:

@Component
public class InitClass{

  private UsarioService usarioService;

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

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

Then this class will handle all the initialization you're doing now in @PostConstruct. It may be required to do this in @PostConstruct as Spring beans may not be fully initialized until then.

However, without seeing how everything is initialized, it's hard to tell what the best strategy would be.




回答2:


Make explicit component scan in the application context file. I did like this and it worked for me.

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

You can see more information in the link here



来源:https://stackoverflow.com/questions/44573884/spring-dependency-injection-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!