SpringBoot uses @ Autowired to inject dependencies into multi implemented interfaces
- 2021-12-12 08:28:22
- OfStack
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