SpringBoot uses @ Autowired to inject dependencies into multi implemented interfaces

  • 2021-12-12 08:28:22
  • OfStack

Directory uses @ Autowired for multi-implementation interface injection dependency problem description method 1: use @ Qualifier to qualify method 2: use @ Autowired to match byName features method 3: use @ Primay1 interface multiple implementation classes Spring injection 1. First, Interface1 interface has two implementation classes 2. Use @ Autowired and @ Qualifier injection 3. Use @ Resource injection to distinguish by default class name 4. Use @ Resource injection to distinguish by the name specified by @ Service

Injecting dependencies into multi-implemented interfaces using @ Autowired

Problem description

Now there is UserRepositoryImpl, which needs to be injected with dependencies.


@Repository
public class UserRepositoryImpl implements UserRepository {
    @Autowired
    private JdbcTemplate jdbcTemplate;
}

In the IOC container in this project, JdbcTemplate has two implementations.


    @Bean(name="primaryJdbcTemplate")
    public JdbcTemplate primaryJdbcTemplate (
            @Qualifier("primaryDataSource")  DataSource dataSource ) {
        return new JdbcTemplate(dataSource);
    }
    @Bean(name="secondaryJdbcTemplate")
    public JdbcTemplate  secondaryJdbcTemplate(
            @Qualifier("secondaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

Method 1: Use @ Qualifier to qualify

Modify in class UserRepositoryImpl to specify the implementation of the injection dependency via @ Qualifier.


@Repository
public class UserRepositoryImpl implements UserRepository {
    @Autowired
    @Qualifier("primaryJdbcTemplate")
    private JdbcTemplate jdbcTemplate;
}

Method 2: Using @ Autowired, byName can match Bean

Change the name of the member variable to be injected in UserRepositoryImpl to id of Bean in IOC container. When injecting dependencies, the IOC container will match it to Bean in the same way as byName and inject dependencies.


@Repository
public class UserRepositoryImpl implements UserRepository {
    @Autowired
    private JdbcTemplate primaryJdbcTemplate;
}

Method 3: Use @ Primay

Add @ Primary annotation to Bean. When @ Autowired encounters a multi-implementation interface, the IOC container injects Bean annotated by @ Primary.


    @Primary
    @Bean(name="primaryJdbcTemplate")
    public JdbcTemplate primaryJdbcTemplate (
            @Qualifier("primaryDataSource")  DataSource dataSource ) {
        return new JdbcTemplate(dataSource);
    }
    @Bean(name="secondaryJdbcTemplate")
    public JdbcTemplate  secondaryJdbcTemplate(
            @Qualifier("secondaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

Spring injection of multiple implementation classes for 1 interface

1. First, the Interface1 interface has two implementation classes

Interface1Impl1 and Interface1Impl2

Interface1 interface:


package com.example.service;
/**
 * Created by liuzh on 2018-05-29.
 *  Interface 1
 */
public interface Interface1 {
    void fun1();
}

Here are two implementation classes of the interface. Please note how the @ service annotation is used. Here, each implementation class is labeled with a different name, which is convenient for different injection when @ Resource injection

Interface1 Interface Implementation Class 1:


@Service("s1")
 public class Interface1Impl1 implements Interface1 {
 @Override 
public void fun1() {
 System.out.println(" Interface 1 Implementation class  ...");
 } 
  public void fun2(){
  System.out.println(" Interface 1 Implementation class 1 fun2 ...");
 } 
}

Interface1 Interface Implementation Class 2:


@Service("s2") 
public class Interface1Impl2 implements Interface1 { 
@Override 
public void fun1() { 
System.out.println(" Interface 1 Implementation class  ...");
 } 
public void fun2(){
 System.out.println(" Interface 1 Implementation class 2 fun2 ..."); 
} 
} 

2. Inject through @ Autowired and @ Qualifier


@Autowired
@Qualifier("interface1Impl1")
Interface1 interface1;    // Normal startup 

3. Use @ Resource injection to distinguish by default class name


@Resource(name = "interface1Impl1")
Interface1 interface1;    // Normal startup 

4. Use @ Resource injection, distinguished by the name specified by @ Service


    @Bean(name="primaryJdbcTemplate")
    public JdbcTemplate primaryJdbcTemplate (
            @Qualifier("primaryDataSource")  DataSource dataSource ) {
        return new JdbcTemplate(dataSource);
    }
    @Bean(name="secondaryJdbcTemplate")
    public JdbcTemplate  secondaryJdbcTemplate(
            @Qualifier("secondaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
0

Related articles: