Spring与IoC:
1.IoC,控制反转,是一个概念和一种思想,是指将传统意义上的由程序代码直接操控的对象的调用权交给了容器,通过容器来实现对象的装配和管理。控制反转本阿里就是对对象控制权的转移,从程序代码本身反转到了外部容器。IoC其实现方式多种多样,最常见的实现方式为"依赖注入"。
(1)依赖注入:DI(Dependency Injection),是指程序运行过程中,若需要调用另一个对象协助时,无需在代码中创建被调用者对象,而是依赖于外部容器,由外部容器创建后传递给程序。依赖注入是目前最优秀的解耦方式。
(2)第一个Spring应用,开发步骤:
I.导入Spring的jar包:
II.定义JavaBean类
III.定义Spring配置文件(通过Spring插件产生)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<!-- 定义一个javabean对象,交给Spring容器来管理 -->
<bean id="myStu" class="com.edu.spring.beans.Student"/>
</beans>
IV.读取Spring配置文件,产生Spring的容器,并通过bean的id得到容器中对应的javaBean对象。
(3)容器中Bean对象的作用域:
在配置bean对象时,可以通过scope属性指定该对象的作用域:
I.singleton:单例模式/单态模式,即整个Spring容器中只有一个实例,默认就是单例的。
II.prototype:原型模式,即每次通过getBean方法获得的实例都是一个新的实例,即多例模式。
例子:见Spring工程
III.request:对于每次HTTP请求,都会产生一个新的bean的实例。
IV.session:对于每次不同的HttpSession会话,都会产生一个不同的bean的实例。
V.global session:每个全局的Http session对应一个bean实例,典型的是仅在使用集群时有效,多个web应用共享一个session.对于一般应用,和session是等同。
对于scope为request、session、global session仅在Web中使用Spring有效。
2.基于XML配置的DI
Spring在调用无参构造函数创建Bean对象后,就需要对Bean对象的属性进行初始化,初始化是由容器自动完成的,称为注入。根据注入方式不同,分为设值注入和构造注入。
(1)设值注入:是指通过javabean的setter方法传入对应的属性值。这种方式简单直观,在Spring的依赖注入中大量使用。
<bean id="student" class="com.edu.spring.beans.Student">
<!-- property表示注入的属性值:name表示待注入值的属性,value为具体注入的值 -->
<property name="name" value="丽丽"/>
<property name="age" value="21"/>
</bean>
I.对于域属性的注入:当某个bean的属性值是另外一个bean的实例时,需要通过ref属性来注入:
<bean id="student" class="com.edu.spring.beans.Student">
<!-- property表示注入的属性值:name表示待注入值的属性,value为具体注入的值 -->
<property name="name" value="丽丽"/>
<property name="age" value="21"/>
<!-- 对于域属性的注入:通过ref去引用另外一个bean的id -->
<property name="school" ref="school"/>
</bean>
例子:见Spring工程
(2)构造注入:在构造调用者实例的同时,完成被调用者的实例化,即使用带参的构造函数设置依赖关系。
<bean id="student2" class="com.edu.spring.beans.Student">
<constructor-arg name="name" value="娜娜"/>
<constructor-arg name="age" value="20"/>
<constructor-arg name="school" ref="school"/>
</bean>
例子:见Spring工程
(3)集合属性注入
<bean id="school" class="com.edu.spring.beans.School">
<property name="name" value="成都信息工程大学"/>
</bean>
<bean id="student1" class="com.edu.spring.beans.Student">
<property name="name" value="丽丽"/>
<property name="age" value="21"/>
<property name="school" ref="school"/>
</bean>
<bean id="student2" class="com.edu.spring.beans.Student">
<property name="name" value="娜娜"/>
<property name="age" value="20"/>
<property name="school" ref="school"/>
</bean>
<bean id="collection" class="com.edu.spring.beans.MyCollections">
<property name="strs">
<!-- 给数组注入值 -->
<array>
<value>abc</value>
<value>def</value>
</array>
</property>
<property name="students">
<!-- 给list集合注入值 -->
<list>
<ref bean="student1"/>
<ref bean="student2"/>
</list>
</property>
<property name="mySet">
<!-- 给set集合注入值 -->
<set>
<value>北京</value>
<value>成都</value>
</set>
</property>
<property name="myMap">
<!-- 给map集合注入值 -->
<map>
<entry key="身高" value="175"/>
<entry key="体重" value="80"/>
</map>
</property>
<property name="myPro">
<!-- 给Properties集合注入值 -->
<props>
<prop key="电话">13800000000</prop>
<prop key="地址">航空港</prop>
</props>
</property>
</bean>
例子:见CollectionDI工程
(4)对于域属性的自动注入
对于域属性的注入,可以不在配置文件中显式的注入,可以通过<bean>标签的autowire属性值,为域属性进行隐式的注入。根据自动注入的标准不同,分为两种:
byName:根据名称自动注入
byType:根据类型自动注入
I.byName自动注入:当配置文件中被调用Bean的id值和调用者Bean的属性名相同的时候,可以使用byName自动注入域属性值。
<bean id="school" class="com.edu.spring.beans.School">
<property name="name" value="成都信息工程大学"/>
</bean>
<bean id="student1" class="com.edu.spring.beans.Student" autowire="byName">
<property name="name" value="丽丽"/>
<property name="age" value="21"/>
</bean>
II.byType自动注入:当配置文件中调用者Bean包含的域属性的类型和配置文件中其中一个<bean>的类型同源(要么相同类型,要么is子类或实现类)时,可以使用byType来根据类型自动注入。根据类型自动注入时,要求被注入的<bean>只能有一个。
<bean id="school" class="com.edu.spring.beans.School">
<property name="name" value="成都信息工程大学"/>
</bean>
<bean id="student2" class="com.edu.spring.beans.Student" autowire="byType">
<property name="name" value="娜娜"/>
<property name="age" value="20"/>
</bean>
例子:见CollectionDI工程
(5)为应用指定多个Spring配置文件。
I.平等关系的配置文件
比如在src目录下创建了三个配置文件:
spring-base.xml
spring-student.xml
spring-teacher.xml
String[] configs={"spring-base.xml","spring-student.xml","spring-teacher.xml"};
ApplicationContext ac=new ClassPathXmlApplicationContext(configs);
II.包含关系的配置文件
各个配置文件中有一个总的配置文件,总配置文件通过<import/>引入其他配置文件。
比如在src目录下创建了三个配置文件:
spring-admin.xml
spring-student.xml
spring-teacher.xml
还有一个总的配置文件:spring_total.xml:
<import resource="classpath:spring-admin.xml"/>
<import resource="classpath:spring-student.xml"/>
<import resource="classpath:spring-teacher.xml"/>
还可以使用通配符"*",可以改写如下:
<import resource="classpath:spring-*.xml"/>
ApplicationContext ac=new ClassPathXmlApplicationContext("spring_total.xml");
3.基于注解的DI
对于注解式的DI,无需在配置文件中声明Bean的实例,只需在JavaBean中使用注解即可完成Bean对象的定义和属性的注入。
(1)开发步骤:
I.导入AOP的包
spring-aop-4.1.0.RELEASE.jar
II.指定扫描基本包
<!-- 扫描注解的基本包 -->
<context:component-scan base-package="com.edu.spring.beans"/>
III.使用注解:
A. @Component(value="bean的id"):在Spring容器中产生bean对象,类似于<bean>标签,其中value属性值即为该bean的id值。如果value属性作为唯一属性,可以省略value的书写。
@Respository 用于对DAO实现类进行注解
@Service 用于对Service实现类进行注解
@Controller 用于对控制器类进行注解
以上上个注解的功能与@Component等效,创建他们的目的是为了对其进行功能扩展,以便以后使其功能不同。
B. @Scope;指定作用域
C. @Value:给属性注入值,类似于<bean>标签的<property>子标签的value属性。使用该注解给属性注入值的时候,无需使用setter方法,若有setter方法,可以加在setter方法上。
D. @AutoWired 按类型自动注入域属性
使用该注解给属性注入值的时候,无需使用setter方法,若有setter方法,可以加在setter方法上。
E. @AutoWired和@Qualifier(value="bean的id")按名称自动注入域属性值
例子:见SpringAn工程