service3中标注@Autowired的2个属性都有值了,都被注入成功了。
案例6:@Autowire标注字段,多个候选者的时候,按字段名称注入
IService接口
package com.javacode2018.lesson001.demo26.test5;
public interface IService {
}
接口来2个实现
2个实现类上都标注了@Component注解,都会被注册到容器中。
Service0
package com.javacode2018.lesson001.demo26.test5;
import org.springframework.stereotype.Component;
@Component
public class Service0 implements IService {
}
Service1
package com.javacode2018.lesson001.demo26.test5;
import org.springframework.stereotype.Component;
@Component
public class Service1 implements IService {
}
来个Service2
package com.javacode2018.lesson001.demo26.test5;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Service2 {
@Autowired
private IService service1; //@1
@Override
public String toString() {
return “Service2{” +
“service1=” + service1 +
‘}’;
}
}
@1:标注了@Autowired注解,需要注入类型为IService类型的bean,满足这种类型的有2个:service0和service1
按照上面介绍的候选者查找过程,最后会注入和字段名称一样的bean,即:service1
来个总的配置类,负责扫描当前包中的组件
package com.javacode2018.lesson001.demo26.test5;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan
public class MainConfig5 {
}
来个测试用例
@Test
public void test5() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig5.class);
for (String beanName : context.getBeanDefinitionNames()) {
System.out.println(String.format(“%s->%s”, beanName, context.getBean(beanName)));
}
}
运行输出
service0->com.javacode2018.lesson001.demo26.test5.Service0@36902638
service1->com.javacode2018.lesson001.demo26.test5.Service1@223d2c72
service2->Service2{service1=com.javacode2018.lesson001.demo26.test5.Service1@223d2c72}
注意最后一行,service2中的service1被注入了bean:service1
案例7:将指定类型的所有bean,注入到Collection、Map中
注入到Collection中
被注入的类型为Collection类型或者Collection子接口类型,注意必须是接口类型,如:
Collection
List
Set
会在容器中找到所有IService类型的bean,放到这个集合中。
注入到Map中
被注入的类型为Map类型或者Map子接口类型,注意必须是接口类型,如:
Map<String,IService>
会在容器中找到所有IService类型的bean,放到这个Map中,key为bean的名称,value为bean对象。
来看案例代码。
来个接口
package com.javacode2018.lesson001.demo26.test6;
public interface IService {
}
来2个实现类,标注@Component注解
Service0
package com.javacode2018.lesson001.demo26.test6;
import org.springframework.stereotype.Component;
@Component
public class Service0 implements IService {
}
Service1
package com.javacode2018.lesson001.demo26.test6;
import org.springframework.stereotype.Component;
@Component
public class Service1 implements IService {
}
再来个类Service2
package com.javacode2018.lesson001.demo26.test6;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Component
public class Service2 {
@Autowired
private List services;
@Autowired
private Map<String, IService> serviceMap;
@Override
public String toString() {
return “Service2{\n” +
“services=” + services +
“, \n serviceMap=” + serviceMap +
‘}’;
}
}
@1:注入IService类型的所有bean
@2:注入一个map
来个总的配置类
package com.javacode2018.lesson001.demo26.test6;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan
public class MainConfig6 {
}
来个测试用例
@Test
public void test6() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig6.class);
for (String beanName : context.getBeanDefinitionNames()) {
System.out.println(String.format(“%s->%s”, beanName, context.getBean(beanName)));
}
}
运行输出
service0->com.javacode2018.lesson001.demo26.test6.Service0@1189dd52
service1->com.javacode2018.lesson001.demo26.test6.Service1@36bc55de
service2->Service2{
services=[com.javacode2018.lesson001.demo26.test6.Service0@1189dd52, com.javacode2018.lesson001.demo26.test6.Service1@36bc55de],
serviceMap={service0=com.javacode2018.lesson001.demo26.test6.Service0@1189dd52, service1=com.javacode2018.lesson001.demo26.test6.Service1@36bc55de}}
注意看一下上面services和serviceMap的值。
@Autowired源码
spring使用下面这个类处理@Autowired注解
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
@Resource:注意依赖对象
作用
和@Autowired注解类似,也是用来注入依赖的对象的,spring容器会对bean中所有字段、方法进行遍历,标注有@Resource注解的,都会进行注入。
看一下这个注解定义:
javax.annotation.Resource
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
String name() default “”;
…其他不常用的参数省略
}
这个注解是javax中定义的,并不是spring中定义的注解。
从定义上可以见,这个注解可以用在任何类型上面、字段、方法上面。
注意点: