前提
本人是正在学习Spring的大三学生,但我在网课和有些博客上看到对IOC自动装配注解方面有些表意不当或者不详细之处,所以这篇文章我想仔细分享我所学的Spring IOC容器自动装配方面的学习收获。建议读这篇文章之前先了解下Spring IOC容器的装配基础知识(组件扫描等等)和Web MVC架构模式。如果有大神发现我的文章哪里有问题的话,请指出来,不胜感激!!
一、IOC基础理解
@Autowired是我们很多人用Spring的IOC都会使用的注解,可以理解成给一个对象注入IOC匹配的对象。
public class BookService
{
@Autowired
private BookDao bookDao;
}
比如在MVC代码中,Service层中就要有对应Dao的对象。以往用原生Servlet开发时,可以在构造方法中创建BookDao对象,然后在其他方法中使用。
public class BookService
{
@Autowired
private BookDao bookDao;
public void BookService()
{
this.bookDao = new BookDao();
}
}
但使用Spring框架控制反转后,这些对象的注入由IOC容器给你注入。
这个就好像车间的零件老师傅,每天早上工厂开工时,这个老师傅大喊一声:“谁需要我帮忙托管你们的工具?”。然后业务人员Service说"帮我托管吧,每次处理业务都要找Dao这个臭老头借工具",Controller等等几位工友也同意把自己的工具给这位零件老师傅托管。这样,零件老师傅把同意了托管的工友的工具都收集起来。然后谁需要用什么工具,直接喊工具的名字或类型,这位老师傅就从自己收集的工具中找到匹配的,马上送过去。这样各个员工就不用自己主动去找别人借工具了。“自己new对象”变为“框架反射出对象交给你”。
到这里,大家应该对控制反转有了基础的了解了,不是由你自己new对象,而是让框架帮你注入。
二、@Autowired匹配规则
@Autowired默认是按找类型来匹配的(byType),所以当在IOC容器中只匹配到一个同类bean的话,这个就没什么说的了,直接注入即可。
public class BookService
{
@Autowired
private BookDao bookDao; // 这里的就是默认按BookDao这个类型来匹配的
}
现在就是要来讨论按类型没匹配到或匹配到多个的情况下,Spring是怎么处理的。
1.没有匹配到对应bean
这种情况,Spring会自动按属性名来进行byName匹配。
public class BookService
{
@Autowired
private BookDao bookDao11;
}
如上面的代码片段,Spring会byName匹配为bookDao11的bean,匹配到了直接注入,否则抛出异常。
2.匹配到多个同类bean
我们先看一个例子。
首先,编写BookDao对象,在BookDao类中加一个属性flag以便标识对象。
public class BookDao
{
public int flag= 0;
public BookDao(int flag) {
this.flag= flag;
}
public BookDao() {
}
@Override
public String toString() {
return "BookDao [flag=" + flag+ "]";
}
}
完善BookService对象,添加print方法,打印bookDao的标识值。
@Service
public class BookService
{
@Autowired
private BookDao bookDao;
public BookService() {
}
public BookService(BookDao bookDao)
{
this.bookDao = bookDao;
}
public void print()
{
System.out.println(bookDao); // bookDao已经重写了toString方法
}
}
我们先创建配置类(这里用配置类代替xml配置文件了)。
@Configuration // 配置类标识
@ComponentScan(value = {
"cn.service", "cn.dao"}) // 包扫描
public class MyConfig
{
@Bean("bookDao1") // 注册一个bean,id为bookDao1,类型为BookDao
public BookDao bookDao1()
{
return new BookDao