Can I use a HashMap to pick which interface (DAO) to autowire in SpringBoot?

Viewed 555

I will try to be as detailed as possible. I have many DAO and my service needs to use one of them based on the key i get. For instance -

if(key.equals("abc") {
   obj = abcDAO.getOne(id);
} else if(key.equals("xyz") {
   obj = xyzDAO.getOne(id);
}

The object is of type parent class and abc, xyz.. are all child classes.

My idea is to create a Map<String, ParentCLass> to get the object just by passing the key instead of If-else so that it will be easy to add for further changes. In case it would've been a normal class, I wouldv'e initialized the map as

Map<String, ParentClass> map. 
map.put("abc", new Abc());

But since DAO are interfaces and require to be @Autowired for using them, I don't know how to proceed. I am a beginner. Any help appreciated.

3 Answers

Spring is able to inject all beans with the same interface in a map if the map has String as key (will contain the bean names) and the interface as value.

public interface MyDao {
    
}

@Autowired
private Map<String, MyDao> daos;

EDIT: If you use Spring Data Repository, there is already a tagging Interface: Repository. You can use below code to inject all DAOs in one bean.

@Autowired
private Map<String, Repository> daos;

EDIT2: Example

public interface UserRepo extends JpaRepository<User, Long> { ... }

@Service
public class MyService {

    @Autowired
    private Map<String, Repository> daos;

    public List<User> findAll() {
        return daos.get("userRepo").findAll();
    }
}

You can create different bean for each of your Dao with a specific name

@Bean(name = "daoImpl1")
public Dao daoImpl1(){
return new DaoImpl1();

@Bean(name = "daoImpl2")
public Dao daoImpl2(){
return new DaoImpl2();

And then @Autowire them using @Qualifier with that name

@Autowired
@Qualifier("daoImpl1")
private Dao daoImpl1;

@Autowired
@Qualifier("daoImpl2")
private Dao daoImpl2;

i made methods to make simple jpa things, i stored all of repositories in the HashMap you just have to pass the child class and you get the corresponding JpaRepository

you can see more at https://github.com/fajaralmu/base_web_app

example :

public List<Page> getAllPages() {
        List<Page> allPages = entityRepository.findAll(Page.class);
        
        return   allPages;
    }

enter image description here

Related