Java接口实现类动态切换

前言

探究数据源动态切换原理, 并进行简单原理演练。

原理演练

  1. dao层基本实现
1
2
3
public interface IDao {
User getUser();
}
1
2
3
4
5
6
7
@Slf4j
public class Dao1 implements IDao{
@Override
public User getUser() {
return new User("dao1", 17);
}
}
1
2
3
4
5
6
7
@Slf4j
public class Dao2 implements IDao{
@Override
public User getUser() {
return new User("dao2", 17);
}
}
  1. dao管理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class DaoContextAdapter {

private final InheritableThreadLocal<String> proxyThreadLocal = new InheritableThreadLocal<>() {
@Override
protected String initialValue() {
return "dao1";
}
};

public String get() {
return proxyThreadLocal.get();
}

public void set(String proxy) {
proxyThreadLocal.set(proxy);
}

public void clear() {
proxyThreadLocal.remove();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class DaoContext {

private static final Map<String, IDao> DAOS = new HashMap<>();
private final DaoContextAdapter adapter;

static {
DAOS.put("dao1", new Dao1());
DAOS.put("dao2", new Dao2());
}

public DaoContext(DaoContextAdapter adapter) {
this.adapter = adapter;
}

public IDao getDao() {
return DAOS.get(adapter.get());
}
}
  1. service层动态切换dao
1
2
3
public interface IService {
User getUser();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
public class UserService implements IService{

private DaoContext daoContext;

public void setDaoContext(DaoContext daoContext) {
this.daoContext = daoContext;
}

@Override
public User getUser() {
return daoContext.getDao().getUser();
}
}
  1. 演练
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Slf4j
class ProxyTest {

@Test
void proxy() throws Exception {
DaoContextAdapter adapter = new DaoContextAdapter();
DaoContext daoContext = new DaoContext(adapter);

UserService userService = new UserService();
userService.setDaoContext(daoContext);

// User(name=dao1, age=17)
adapter.set("dao1");
log.info(userService.getUser().toString());

// User(name=dao2, age=17)
adapter.set("dao2");
log.info(userService.getUser().toString());

}
}