clanofsol
clanofsol

Reputation: 93

Spring dependency injection not working

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" />

Upvotes: 2

Views: 13581

Answers (2)

Upendra Sharma
Upendra Sharma

Reputation: 51

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

Upvotes: 0

Christopher Schneider
Christopher Schneider

Reputation: 3915

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.

Upvotes: 3

Related Questions