简体   繁体   中英

Spring: Inject a dependency

I am new with Spring and I have some questions and problems with the injection (and maybe with the choosen arquitecture)

I have two projects (desktop application) and an application that acts like an API (new and made with Spring)

The first application uses the methods of the API (Services...)

From the desktop application this piece of code is called

ServiceManager serviceManager = ServiceManager.getInstance(dbConn.getConnection());
FirstService firstService = (FirstService)serviceManager.getService(Table.FIRST);
System.out.println("Count: " + firstService.count());

And in the API application, there are two differents modules, Service and DAO modules.

In the Service module:

public class FirstServiceImpl extends GenericService implements FirstService {

private final static String TABLENAME = "FIRST";

@Autowired
FirstDAO firstDAO;

public FirstServiceImpl(Connection con) {
    super(con, TABLENAME);
}

public int count() throws SQLException {
    firstDAO.init(connection);
    return firstDAO.count();
}}

public class ServiceManager {

private Connection con;
private static ServiceManager instance;

public ServiceManager(Connection con) {
    super();
    this.con = con;
}

public static ServiceManager getInstance(Connection connection) {
    if (instance == null) {
        instance = new ServiceManager(connection);
    }
    return instance;
}

public GenericService getService(Table t) throws SQLException {

    switch (t) {
    case FIRST:
        return new FirstServiceImpl(this.con);
    case SECOND:
        //return new SecondDAO(this.con);
    default:
        throw new SQLException("Trying to link to an unexistant service.");
    }
}

In the DAO module

@Configuration
public class DAOConfig {

    @Bean
    public FirstDAO firstDAO() {
        System.out.println("Scans!");
        return new FirstDAOImpl();
    }
}

and the FirstDAOImpl, which is not relevant.

my application-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config />

    <context:component-scan base-package="com.ddd.iker.dao" />

</beans>

DAOConfig is in com.ddd.iker.dao

My problem is that I get always a null pointer exception in the FirstServiceImpl when I try to do firstDAO.init()

I tried using this piece of code in the method .getInstance of the ServiceManager.

GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.load("classpath:application-context.xml");
ctx.refresh();

The @Bean is scan, but I get the same exception.

And if I set this piece of code in the constructor of the FirstServiceImpl, it works (without Autowired) but I don´t think that is the best approach, because I would like to use the annotations.

GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.load("classpath:application-context.xml");
ctx.refresh();
firstDAO = ctx.getBean("firstDAO", FirstDAO.class);
ctx.close();

How can I get the firstDAO with the @Autowired annotation and without the above code? How should I manage the application-context? I really appreciate any critic.

The @Autowired annotation will not work on components that aren't initialized by the Spring container. You are creating the FirstServiceImpl by hand, calling a parametrized constructor. Spring components also need a constructor which takes no arguments (the default constructor will also work if you do not explicitly specify one) because of the mechanism that Spring uses to create them (by reflection). You shall annotate you service classes with the @Service and your DAOs with the @Repository annotation to work properly. The main thing that you have to remember is to let Spring initialize as much components (services, DAOs, other beans) as possible. Therefore you can @Autowire them into other Spring components.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM