Spring IOC

Spring IOC

木头人 951 2018-12-08

什么是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容器管理程序组件,创建组件对象,利用注入建立对象关系。


# spring # Ioc # java # 后端