spring工厂的自动注入
一、仅一个实现类
这种情况最简单,只需要直接使用@Autowired按类型注入,安全快捷,当然你也可以用@Resource @Qualifier注入,也可以final修饰,写构造方法注入。如:
@RequiredArgsConstructor
public class TestMain {
private final InterfaceThree three;
}
二、当前接口有多个实现类
如果一个接口有多个实现类,那么你再使用上面的方法就不行了,会报注入异常,但是有时候你就是会有多个实现类 ,那该怎么办呢?
2.1 List方式注入
如果你在写适配器时,你是并不知道未来实现你接口的时候,别人是怎么定义他们的类名的。这个时候,另外一种注入方式就出来了:
/**
* 你暴露的接口
*/
public interface InterfaceOne {
String one();
}
/**
* 实现类1
*/
@Component
public class OneImpl implements InterfaceOne{
@Override
public String one() {
return "one";
}
}
/**
* 实现类2
*/
@Component
public class One2Impl implements InterfaceOne{
@Override
public String one() {
return "two";
}
}
这个时候,你不知道他们的类名,你不能使用名字注入,这个时候,你可以这样:
首先对接口进行一些改造-增加一个校验方法:
/**
* 你暴露的接口
*/
public interface InterfaceOne {
String one();
boolean check(int code);
}
这样子你的实现类都需要实现这个方法,我们可以对这个校验进行一个规则限制:
/**
* 实现类1
*/
@Component
public class OneImpl implements InterfaceOne{
@Override
public String one() {
return "one";
}
@Override
public boolean check(int code) {
return code==1;
}
}
/**
* 实现类2
*/
@Component
public class One2Impl implements InterfaceOne{
@Override
public String one() {
return "two";
}
@Override
public boolean check(int code) {
return code==2;
}
}
这个code我们可以放数据库,可以写enum,这个就很灵活了。
我们在使用时,就可以这样:
@RequiredArgsConstructor
public class TestMain {
private final List<InterfaceOne> ones;
public void Test(){
int code = 1;
String result = ones.stream()
.filter(one->one.check(code))
.map(one-> one.one())
.collect(Collectors.toList()).get(0);
System.out.println(result);
}
}
2.2 Map方式注入
当然不是只有这种情况,也许还有这么一个场景:一个业务有两种处理方式,根据传来的标识进行选择哪种处理方式。就好像我们在登录的时候,我们可以选择账号密码登录,也可以选择手机号加验证码登录,这时候,我们是知道两种方式的name的。这样子我们可以选择另一种注入方式-map
初始的接口与2.1类似,就不累赘了,直接上改造后的:
@Component("two")
public class TwoImpl implements InterfaceTwo {
@Override
public String two() {
return "two";
}
}
@Component("two2")
public class Two2Impl implements InterfaceTwo {
@Override
public String two() {
return "two2";
}
}
可以看到,我们只是改了@Component的value值而已,也就是改了类在spring工厂中的名字,接下来就是使用了:
@RequiredArgsConstructor
public class TestMain {
private final Map<String, InterfaceTwo> twos;
public void Test(){
String result2 = twos.get("two").two();
System.out.println(result2);
}
}
ok,是不是很简单。