Spring IOC
### 什么是IOC
```Text
Inversion Of Control 控制反转
控制反转的意思就是 程序中需要某个对象时 由原来的 new的方式
转换成了由容器来进行创建 管理 和 维护。
这样做的好处是可以大大做到降低组件之间的耦合度。
```
### Spring 容器
任何java类 都可以由Spring 容器来创建对象 并由容器来进行管理和维护使用
Spring 容器 实现了 IOC 和 AOP 机制
Spring 容器的类型 有 BeanFactory 和 ApplicationContext
1 Spring 容器的使用步骤
```XML
1 建立一个项目 导入jar包(ioc) 并拷贝Spring 容器对应的配置文件到src下
2 在Spring 容器中 配置 bean 的说明
3 创建一个Spring 容器对象 从容器中获取javaBean 对象
```
2 Spring 容器创建对象的三种方式
```XML
1 构造器方式实例化
默认调用类型对应的无参构造
2 静态工厂方法实例化
Calendar
3 实例工厂方法实例化
使用一个已经存在的对象 来创建另外一个类型的对象
```
3 Spring 容器中对象的作用域
```Text
Spring 容器中对象 默认的作用域是单例的 singleton,可以通过 bean标记的 scope属性
来指定成非单例的取值为 prototype 。 其它的如何request session 等会在web部分涉及。
```
4 Spring容器中对象的初始化 和销毁
```Text
1 初始化
在beans标记中 加 default-init-method="方法名" 这样会影响到spring容器中所有的对象 这样影响范围比较大
所有类型没有对应的初始化方法时 也不会报错。
也可以在bean标记中加 init-method="方法名" 这时只影响到这一个bean 所有这个bean 对应的类型 没有对应的初始化方法时 会报错。
2 销毁
在beans标记中 加 default-destroy-method="方法名" 这样会影响到spring容器中所有的对象 这样影响范围比较大 所有类型没有对应的销毁方法时 也不会报错。
也可以在bean标记中加 destroy-method="方法名" 这时只影响到这一个bean 所有这个bean 对应的类型 没有对应的销毁方法时 会报错。 只针对单例对象。
```
5 单例对象的 延迟实例化
```Text
可以通过bean 标记的 lazy-init 属性 这个属性默认是false 指定成true 就延迟实例化
```
### 什么是DI
```Text
Dependence Injection 依赖注入(依赖注射)
一个组件对象 需要一份数据 或者是另外一个对象时 通过一定的手段 把数据设置到合适位置的过程 叫依赖注入。
它的作用 就是解决 容器中组件的装配问题。
```
### 实现DI的方式
1 setter 注入
```XML
这种方式 参考的是 set方法 具体的参考准则是 去掉set 然后首字母小写。
value 适合赋值简单值(八种基本类型 以及封装类 String 枚举) 如果是其它的复杂值
则需要使用 ref 进行赋值 ref的值就是容器中的组件id。
```
2 构造器注入
```Text
这种方式 参考的是 构造方法 看构造方法对应的参数
把property 换成 constructor-arg name 就是参数名
除了使用name 指定参数 还可以使用 index 指定参数 下标从0开始
```
3 自动注入
```Text
一般是用来解决复杂值的注入问题
在bean 标记中 加一个 autowire 属性 取值有 byName 通过容器中组件id 和 属性名一致
来完成装配。还可以取值 byType 根据成员变量对应的类型 来进行匹配 但是类型可能会冲突。
constuctor 采用构造方法匹配 并且这个优先使用 类型匹配 如果有冲突 则启用名字查找 。
```
### bean 参数的注入
1 简单的参数值注入
```Text
八种基本类型 和 对应的封装类 以及String 还有枚举 都使用 value 注入即可
也可以value 标记赋值 还可以使用 代表空值
```
2 复杂值的参数注入
```Text
把上面的 value 换成 ref 即可
```
3 集合类型的参数注入
```XML
java中的 List Set Map Properties 这些集合都可以采用配置文件的
标记来进行注入。
List ----
Set ----
Map -----
Properties -- 值
```
4 集合的单独定义
```XML
Set Map 都类似 比较特殊的是 Properties
jack马
李伟杰
李元霸
```
### Spring 中的EL的表达式
```Text
这个表达式从spring 容器中取值 语法是 把之前的$换成 #
```
### 什么是组件扫描
```Text
Component Scan 组件扫描技术 是Spring 提供的一套基于注解(标注)
用来解决组件的创建 组装 维护组件关系的技术 这个技术可以大大的简化XML的编写。
```
### 如何完成组件扫描
```Text
1 建立一个项目 导入jar包(ioc aop) 拷贝配置文件到 src
2 自定义一个java 类
3 在配置文件中开启组件扫描
4 在java类上 打对应的标注
@Component 通用层标注
@Repository 持久层标注
@Service 业务层标注
@Controller 控制层标注
5 创建Spring 容器 从容器中获取组件进行测试
```
### 和组件扫描相关的其它标注
```Text
控制作用域的标注 @Scope("singleton") 可以通过 prototype 调整成非单例
控制初始化的标注 @PostConstruct 加在初始化方法上 完成对象初始化
控制销毁的标注 @PreDestroy 加在销毁方法上
```
### 组件装配相关的标注
```Text
1 @Value
用在 成员变量 set方法上 如果是赋值简单值 直接@Value("值")
如果是复杂值 则使用 @Value("#{对象id}")
2 @Autowired
用在 成员变量 set方法 还有构造方法上 它是解决复杂值注入问题的
它优先使用类型进行匹配 如果类型有冲突 则启用名字进行匹配。
@Qualifier("cc") 可以结合 @Qualifier 来指定名字查找 找不到会报错 不再启用类型
@Autowired 对组件的依赖 默认属于强依赖 可以通过 required = false 指定弱依赖
@Qualifier 不能用在构造方法上
3 @Resource
用在 成员变量 set方法 它是解决复杂值注入问题的
它优先使用名字进行匹配 如果匹配不上 会启用类型
它是JDK 中的标注 但是可以完美的和Spring 结合
它可以指定名字查找 需要使用name 属性来指定 不能解决强依赖
```
### 总结
Spring是一个容器(IOC核心/AOP)。
Spring容器对象创建?
```XML
BeanFactory-->ApplicationContext-->ClassPathXmlApplicationContext
ApplicationContext ac = new ClassPathXmlApplicationContext("xxx.xml");
```
向Spring容器添加元素(组件)?
```XML
1. 在XML文件添加定义
2. 使用注解扫描技术,@Controller\@Service\@Repository\@Component\@Autowired\@Resource
@Named @Inject
```
从Spring容器获取元素(对象)?
```XML
容器外:ac.getBean("id|name名")
容器内:@Autowired、@Resource/、
```
Spring IOC概念:由Spring容器管理程序组件,创建组件对象,利用注入建立对象关系。