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