作者:小脑斧
链接:https://www.zhihu.com/question/39356740/answer/2299259925
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
@Autowired
应用
有些使用不是很重要,知道有这样的用途就行。
官方地址:@Autowierd
(非重点)将 Autowired 应用于构造器上
As of Spring Framework 4.3, an @Autowired annotation on such a constructor is no longer necessary if the target bean defines only one constructor to begin with. However, if several constructors are available and there is no primary/default constructor, at least one of the constructors must be annotated with @Autowired in order to instruct the container which one to use. See the discussion on constructor resolution for details.
(非重点)将 Autowired 应用于set方法
(非重点)将 Autowired 应用于常规方法
重点 将 Autowired 应用于字段上
重点:@Autowierd是根据类型装配,也就是autowireByType,所以一定要明确唯一类型。可以看底下的示例来理解
@Autowired required属性
可以通过该属性决定是否注入,可以从@Autowierd的源码实现中发现
剖析Autowired 实现
组件
AutowiredAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor
Autowired 和@Resource的不同
Autowired 使用示例
@Autowierd实现依赖注入(接口),首先我们测试@Autowierd通过类型装配
@RestController
public class UserController {
@Autowired
private UserService userService;
public void getName(){
userService.getName();
}
}
接口UserService
public interface UserService {
void getName();
}
实现类一 UserServiceImpl1
@Service
public class UserServiceImpl1 implements UserService{
@Override
public void getName() {
System.out.println("UserService1Impl");
}
}
实现类二 UserServiceImpl2
@Service
public class UserServiceImpl2 implements UserService {
@Override
public void getName() {
System.out.println("userServiceImpl2");
}
}
Main启动类
@ComponentScan("org.example.mang")
public class AppConfig {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
// 获取bean工厂BeanFactory获取UserController
UserController userController = context.getBean(UserController.class);
userController.getName();
}
}
报错
报错原因
在我们的实例中@Autowierd标注的是接口,在之后会根据接口解析接口关联的实现类,在方法DefaultListableBeanFactory#doResolveDependency发现匹配的Bean大于1,于是决定先使用哪个,其实就是看
- 哪个加了@Primary,我们的示例中都没有加,所以这里的autowierdBeanName为null
- 哪个Priority更高,两个都没有实现,一样优先级
- 极为特殊的场景,将Bean放入DefaultListableBeanFactory的resolvableDependencies中,可以直接从这里面拿
- 根据名称匹配
这四个条件对于两个Service实现类来说处于同一竞争水平,所以两个都不会被选择,也就是说result为null。并且之后判断确认是不是想要注入集合Bean,我们这里当然也不是,只注入一个,所以抛异常