DI(依赖注入)
依赖注入(Denpdency Injection, DI)
java文件中导入的包是父类的,但注入的是子类,使用时用的是子类。
概念:利用spring容器给属性赋值
给pid和name赋值的过程就是DI
依赖注入的方式
Xml:
Setter方法来注入:
说明:
- spring容器实例化person和student两个对象
- 利用java的反射机制调用属性的setter方法赋值
- 在客户端利用getBean方法把spring容器中的一个对象获取了。
说明:
- 启动spring容器
- 实例化person对象和student对象
- 给person中的属性赋值
- 调用person的init方法初始化
客户端利用context.getBean获取对象
说明:
- 启动spring容器
- 实例化person对象
- 因为person对象依赖于student对象,所以在实例化person对象的时候必须实例化student对象,所以这个时候第一次调用student,student完成实例化,lazy-init为true也就是第一次调用的时候实例化。
说明:
- 启动spring容器
- 实例化student
- 在客户端执行getBean方法获取person对象
- 实例化person对象,调用person的构造函数
- 调用person中的setStudent方法,给person中的student赋值
- 执行person中的init方法
- Person对象调用方法
带参数构造器IOC
这样客户端创建对象的时候就会调用带参数的构造器完成对象创建和对部分属性的赋值
说明:
- constructor-arg代表指定的构造器函数的其中的一个参数
- 可以利用index,ref,value,type来指定唯一的构造器
- 如果一个bean的配置中没有constructor-arg属性,则必须利用默认的构造函数创建对象。
- 所以在写一个javabean的时候,应该提供属性的setter方法,默认的构造器,带参数的构造器
依赖注入用到的注解
@Resource
不用写set和get方法
@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
在spring的配置文件中
说明:
- 启动spring容器
- spring容器内部创建了两个对象person和student
- 当spring容器解析到
<context:annotation-config />
启动依赖注入的注解解析器:
- spring容器在容器中查找所有的bean(prerson,student)
- 看哪些bean的属性上面是否有注解
- 如果属性上面有该注解,再次检查是否有name属性
- 如果没有name属性,则会把该注解标注的属性的名称获取到和spring容器中的bean标签中的id做匹配,如果匹配成功,则赋值,如果匹配不成功,则按照类型(即属性类型与xml中class指定的类)进行匹配,如果匹配成功,则赋值,如果匹配不成功,则报错。
- 如果有name属性,则把name属性的值解析出来和spring容器中的id做匹配,如果匹配成功,则赋值,如果匹配不成功,则报错。
- 从上述的步骤可以看出注解的效率比较低,xml的效率比较高,注解书写比较简单,xml书写比较复杂。
@Autowired
按照类型匹配
在默认情况下使用 @Autowired
注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个
required 属性默认是true,表示注入的时候,该bean必须存在,否则就会报错(BeanCreationException 异常)。修改为ffalse后在找不到匹配 Bean 时也不报错。
@Qualifier
按照ID匹配,注解只能应用于引用类型