您的位置:首页 > 编程语言 > Java开发

Spring应用(一) IOC和DI总结

2016-04-26 10:21 701 查看

一、IOC和DI的概念描述

1.1概念

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI)。

1.2技术描述

Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。

采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。

1.3实现方法

实现控制反转主要有两种方式:依赖注入和依赖查找。两者的区别在于,前者是被动的接收对象,在类A的实例创建过程中即创建了依赖的B对象,通过类型或名称来判断将不同的对象注入到不同的属性中,而后者是主动索取响应名称的对象,获得依赖对象的时间也可以在代码中自由控制。

二、Spring IOC详解

Spring的控制反转:把对象的创建、初始化、销毁等工作都交给Spring容器来做。由Spring容器控制对象的声明周期。

2.1步骤

A.启动spring容器

1、在类路径下寻找配置文件来实例化容器

ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});可以在整个类路径中寻找xml文件
* 通过这种方式加载。需要将spring的配置文件放到当前项目的classpath路径下
*  classpath路径指的是当前项目的src目录,该目录是java源文件的存放位置。


2、在文件系统路径下寻找配置文件来实例化容器

ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\\beans.xml“});Spring的配置文件可以指定多个,可以通过String数组传入。


注:经常用第一种方法启动容器

B.从spring容器中提取对象

2.2 配置文件中的属性

2.2.1 别名(alias)

<beans>
<bean name="person" class="cn.alias.spring.Person"/>
<alias name="person" alias="p"/>
</beans>


通过这样的配置,可以达到在一个地方命名,在多个地方使用不同的名字的效果。

2.2.2 bean对象的scope

singleton(默认值)

在每个Spring IoC容器中一个bean定义只有一个对象实例(共享)。

默认情况下会在容器启动时初始化bean,但我们可以指定Bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。如:

<bean id="xxx" class="cn.OrderServiceBean" lazy-init="true"/>


如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,如下:

<beans default-lazy-init="true“ ...>




prototype

允许bean可以被多次实例化(使用一次就创建一个实例) . Spring不能对一个prototype bean的整个生命周期负责.这就意味着清楚prototype作用域的对象并释放任何prototype bean所持有的昂贵资源都是客户端的责任。

2.2.3 Lazy-init

Spring默认在启动时将所有singleton bean提前进行实例化。提前实例化意味着作为初始化的一部分,ApplicationContext会自动创建并配置所有的singleton bean.通常情况下这是件好事。因为这样在配置中有任何错误能立即发现。

Lazy-init=”true or false”

Lazy-init 为false,spring容器将在启动的时候报错(比较好的一种方式)

Lazy-init 为true,spring容器将在调用该类的时候出错。

2.2.4init、destroy

Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法。

<bean id=“foo” class=“...Foo” init-method=“setup” destory-method=“teardown”/>


当foo被载入到Spring容器中时调用init-method方法。当foo从容器中删除时调用destory-method(scope = singleton有效)

2.3 创建对象的三种方式

2.3.1 无参构造函数

<bean id=“personService" class="cn.bean.impl.PersonServiceImpl"/>


* 要求PersonServiceImpl有无参构造方法

* spring容器在默认的情况下使用默认的构造函数创建对象

2.3.2 静态工厂方法

<bean id="personService" class="com.factory.PersonServiceFactory" factory-method="createPersonService" />

public class PersonServiceFactory {
public  static PersonService createPersonService(){
return new PersonServiceImpl();
}
}


/**
* 在spring容器 内部,调用了PersonServiceFactory中的createPersonService方法
* 而该方法的内容就是创建对象的过程,是由程序员来完成
*/


2.3.3 实例工厂

<bean id="helloWorldFactory" class="com.spring.ioc.createobject.method.HelloWorldFactory2"></bean>

<!--
factory-bean指向了实力工厂的bean
factory-method实例工厂对象的方法
-->
<bean id="helloWorld" factory-bean="helloWorldFactory" factory-method="getInstance"></bean>


/**
* 实例工厂
*   1、spring容器创建一个实例工厂bean
*   2、该bean调用了工厂方法getInstance产生对象
*/


三、Spring DI详解

依赖注入(Dependence Injection)是把Spring创建的对象注入到Java类中

有三种注入方式,分别为setter注入,构造器注入,注解注入,其中前两种方法都是在xml文件中配置

3.1 setter注入

<bean id="person" class="com.spring.di.xml.setter.Person">
<!--
property描述的就是bean中的属性
name属性就是描述属性的名称
value就是值   如果是基本属性(String),就用value赋值
ref  如果是引用类型,用ref赋值
-->
<property name="pid" value="1"></property>
<property name="name" value="王二麻子"></property>
<property name="student" ref="student"></property>
<property name="lists">
<list>
<value>list1</value>
<value>list2</value>
<!--
list中存放一个student对象
-->
<ref bean="student"/>
</list>
</property>
<property name="objects">
<list>
<value>obj1</value>
<ref bean="student"/>
</list>
</property>
<property name="sets">
<set>
<value>set1</value>
<ref bean="student"/>
</set>
</property>
<property name="map">
<map>
<entry key="m1">
<value>m1</value>
</entry>
<entry key="m2">
<ref bean="student"/>
</entry>
</map>
</property>
<property name="properties">
<props>
<prop key="p1">p1</prop>
<prop key="p2">p2</prop>
</props>
</property>
</bean>


3.2 构造器注入

<bean id="person" class="com.spring.di.xml.constructor.Person">
<!--
constructor-arg  代表某一个构造器的参数
index 构造器参数的下标
value
ref
type  类型
-->
<constructor-arg index="0" value="1" type="java.lang.String"></constructor-arg>
<constructor-arg index="1" ref="student"></constructor-arg>
</bean>

Person类中:

public Person(String name,Student student){
this.name  = name;
this.student = student;
}


3.3 注解注入

3.3.1 步骤

步骤:

A.在配置文件中,引入context命名空间

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring- beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">


B.在配置文件中加入context:annotation-config标签

<context:annotation-config/>


这个配置隐式注册了多个对注释进行解析处理的处理器

AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,

PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor

注: @Resource注解在spring安装目录的lib\j2ee\common-annotations.jar

3.3.2 @Resource

1、@Resource注解和@Autowired一样,也可以标注在字段或属性的setter方法上.

2、@Resource注解默认按名称装配。

名称可以通过@Resource的name属性指定,如果没有指定name属性,

•当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象

•当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。

/**
* 1、启动spring容器
* 2、把spring配置文件中的bean实例化(person,student)
* 3、当spring容器解析配置文件
*     <context:annotation-config></context:annotation-config>
*    spring容器会在纳入spring管理的bean的范围内查找哪些类的属性上是否加有@Resource注解
* 4、如果在属性上找到@Resource注解
*      如果@Resource的注解的name属性的值为""
*           则把@Resource所在的属性的名称和spring容器中的id作匹配
*                  如果匹配成功,则赋值
*                  如果匹配不成功,则会按照类型进行匹配
*                      如果匹配成功,则赋值,匹配不成功,报错
*      如果@Resource的注解的name属性的值不为""
*           则解析@Resource注解name属性的值,把值和spring容器中的ID进行匹配
*               如果匹配成功,则赋值
*               如果匹配不成功,则报错
*
* 说明:
*     注解代码越来越简单,效率越来越低
*     注解只能应用于引用类型
*/


@Autowired和@Qualifier结合起来用与@Resource效果一样

3.3.3 @Autowired

这两个注解的区别是:@Autowired 默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。

3.3.4 @Qualifier

3.3.4 @PostConstruct

指定Bean的初始化方法

3.3.4 @PreDestroy

指定Bean的销毁方法

3.4 Spring中的继承

Spring-Context之九:在bean定义中使用继承

作者:黄博文@无敌北瓜
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: