这篇博客是我在学习 Spring 源码过程中的一个小小的总结,只为了个人记录以及后续学习。希望这篇博客对初学者有所帮助,也希望大神能够得到大神的指导。
依赖注入是经常使用到 @Autowired 和 @Resource 这两个注解(具体怎么使用,网上大堆)。
@AutoWried : 根据类型装配 bean,类型不存在时,根据 name 匹配
@Resource : 根据 name 匹配 bean 进行装配
@Autowried 可以根据属性名称自己装配,但是装配只能依据小驼峰的格式进行匹配
下面是测试代码和各种情况。
AppConfig.java
@Configuration
@ComponentScan("com.example.demo")
public class AopConfig {
}
Service.java
public interface Service {
public void print();
}
CityService.java
@Component
public class CityService implements Service {
@Override
public void print() {
System.out.println("CityService");
}
}
OrderService.java
@Component
public class OrderService implements Service{
@Override
public void print() {
System.out.println("OrderService");
}
}
情况1:
PersonService.java
@Component
public class PersonService {
@Autowired
private Service cityService;
@Autowired
private Service orderService;
public void test1(){
cityService.print();
}
public void test2(){
orderService.print();
}
}
test.java
//@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
// AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AopConfig.class);
// CityService c1 = ac.getBean(CityService.class);
// CityService c2 = ac.getBean(CityService.class);
// System.out.println(c1 == c2);
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AopConfig.class);
PersonService p1 = ac.getBean(PersonService.class);
p1.test1();
p1.test2();
}
}
运行结果:
由于 CityService 和 OrderService 都实现了 Service,因此在使用上述情况注入时,会自动映射到对应的 bean。
CityService
OrderService
情况2 :
在注入时 CityService 和 OrderService 都为大驼峰形式。
@Component
public class PersonService {
@Autowired
private Service CityService;
@Autowired
private Service OrderService;
public void test1(){
CityService.print();
}
public void test2(){
OrderService.print();
}
}
运行结果:
程序会自动报错。
原因:
Spring 的容器(IOC),可以理解成 Map<String,Object> 对象(虽然这么理解不合适,目前可以这么理解)。因为Spring 自动装配 bean 时,会以对应 类小驼峰的名称为key 和 对应的 bean 为 value 存放在 singletonObjects(单例池) 对象中。getBean 时会以对应类的小驼峰为 key 从 singletonObjects 对象中直接获取。由于在这种情况下 CityService 和 OrderService 为 大驼峰形式,因此获取不到报错。
情景3:
@Component
public class PersonService {
@Resource(name = "orderService")
private Service cityService;
@Autowired
private Service orderService;
public void test1(){
cityService.print();
}
public void test2(){
orderService.print();
}
}
运行结果:
虽然时 cityService,但是@Resource(name = "orderService") 指定了 bean 的名称
OrderService
OrderService
注意:当 @Resource(name = "OrderService") 为大驼峰格式时,依旧会报错。