1前言
2基本原理
3IOC容器
4Bean
5依赖
5.1依赖注入
5.2自动装配
自动装配,是一种自动化地进行依赖注入的机制,IOC容器使用此机制实现bean之间依赖关系的自动绑定,该机制具有如下的优点:
|
在XML类型的配置元数据中,自动装配的模式对应标签bean的属性autowire,其支持的模式如下所示:
no 模式 不使用自动装配的依赖注入模式,开发者需要在配置元数据中指定bean的依赖关系,不建议经常变化依赖注入的模式 |
byName 模式 根据依赖项的名称自动装配,例如,Bean中存在依赖项abc,IOC容器使用setter方法的方式自动地执行setAbc方法注入名称是abc的依赖bean |
byType 模式 根据依赖项的类型自动装配,在IOC容器中使用类型注入的模式的时候,被注入的类型的实现必须保持唯一,否则IOC容器会出现异常,因为,IOC容器无法决定注入何种类型的实现(同一个抽象类型的多种实现) |
constructor 模式 使用构造函数自动装配,在IOC容器中使用构造函数注入的模式的时候,被注入的类型的实现必须保持唯一,否则IOC容器会出现异常,因为,IOC容器无法决定注入何种类型的实现(同一个抽象类型的多种实现) |
byType类型、constructor类型支持集合的依赖注入,IOC容器会根据类型判断自动注入对应的bean到指定的集合中。
自动装配的限制与缺点
通常在同一个工程项目中只使用同一种依赖注入的模式,否则很容易出现混淆,不利于维护代码的可读性,自动装配的依赖注入模式既有优点也有缺点,其限制与缺点如下所示:
|
IOC容器也提供配置元数据属性的方式支持一些特殊的使用场景,如下所示:
|
自动装配的依赖注入模式支持Java代码注解的方式是:@Autowired。
5.3方法注入
一般情况下,IOC容器的bean实例对象都是单例的,这些对象在IOC容器中只被创建一次,在IOC容器的生命周期内,所有业务逻辑的处理都使用单例对象。假设存在单例对象A、单例对象B,而且A依赖B,A使用B的方法m0,如果新的业务逻辑是单例对象A每次业务逻辑处理都需要使用非单例对象B的方法m0,则旧的依赖注入方式不再适用于新的业务逻辑。因此,IOC容器提供方法级别(函数级别)的依赖注入、创建新bean的方式支持以上的新的业务场景。
类CommandManager是一个命令管理器,使用命令设计模式,该模式是一种代理执行的模式,由调用者提供执行的命令、命令行参数,管理器负责执行对应的命令、返回命令执行结果、记录命令执行日志或者其他维护功能 |
以上定义的类CommandManager只是使用Spring-Framework提供的功能支持创建全新的bean实例对象(方法createCommand),未使用配置元数据的方式,使用IOC容器创建一个新的名称是command、类型是Command.class的bean实例对象 |
查找方法注入
IOC容器提供方法级别的依赖注入,例如,假设存在名称是A、B的Bean,IOC容器支持使用B的方法替换A的方法,也就是,当A调用某个方法的时候,实际上是调用B的方法。该方法的实现是使用CGLIB的动态代理技术,由于Java只支持接口的代理而不支持实现类的代理,因此,CGLIB需要动态地生成字节码覆盖已存在的方法或者生成新的覆盖方法,从实现Bean的方法替换。
类CommandManager是抽象类,执行命令的时候每次都是创建新的命令(类同于每次都需要创建一个新的非单例bean,其对应原型bean),则IOC容器使用CGLIB技术生成字节码覆盖createCommand方法,并且在覆盖方法中返回新的、名称是myCommand的非单例bean |
使用Java注解Lookup绑定新创建的bean,指定具体bean的名称、根据返回类型两种绑定方式 |
任意方法替换
IOC容器支持可替换任何方法的依赖注入。
类MethodReplacer是一个替换任何方法的执行器接口,其方法reimplement的参数包括传入被替换的对象、被执行的方法、被执行方法的参数 |
替换类MyValueCalculator的方法computeValue,使用执行器的方法reimplement执行 |
(未完待续)