Spring(一)Spring IOC容器配置详解——基于xml文件形式
一、Spring
spring是一个轻量级的框架,相当于一个平台性质,大大简化了Java企业级应用的开发,提供了强大的、稳定的功能。Spring框架大约由20个功能模块组成,这些模块被分为6个部分,如图所示:
Spring Core是最基础部分,提供了IOC特性;Spring AOP是基于Spring Core的符合规范的面向切面编程的实现。
Spring IOC容器是Spring最核心的部分,IOC(Inversion of Control),控制反转,也被称为依赖注入,是面向对象编程中的一种设计理念,用来降低程序代码之间的耦合度。通俗点讲,在实际应用中,多个类之间需要互相依赖才能完成某些特定的业务,而依赖注入就是以配置文件的方式来维护类与类之间的关系,而非硬编码,从而降低了系统之间的耦合,增大了可维护性。
二、搭建环境
先来一个简单的HelloWorld1.下载spring的jar包:http://projects.spring.io/spring-framework/(本文使用的是4.1.4的版本)
2.创建普通的java项目(不一定非得是web项目,简单起见)
3.添加jar包:
- spring-aop-4.1.4.RELEASE.jar
- spring-beans-4.1.4.RELEASE.jar
- spring-context-4.1.4.RELEASE.jar
- spring-context-support-4.1.4.RELEASE.jar
- spring-core-4.1.4.RELEASE.jar
- spring-expression-4.1.4.RELEASE.jar
- commons-logging.jar//此jar包为第三方类库,需要自行下载
(1)Student类:
- package com.wzj.entity;
- public class Student {
- private int id;
- private String name;
- //省略get、set方法
- //为了方便显示,重写了toString方法
- @Override
- public String toString() {
- return "Student [id=" + id + ", name=" + name + "]";
- }
- }
(2)spring-config.xml文件的配置:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:p="http://www.springframework.org/schema/p"
- xmlns:util="http://www.springframework.org/schema/util"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
- http://www.springframework.org/schema/util
- http://www.springframework.org/schema/util/spring-util-4.0.xsd
- http://www.springframework.org/schema/p
- http://www.springframework.org/schema/p/spring-p-4.0.xsd">
- <!-- 以这种方式来声明Student类的实例 -->
- <bean id="student" class="com.wzj.entity.Student">
- <!-- 为Student对象的属性赋值 -->
- <property name="id" value="1"/>
- <property name="name" value="张三"/>
- </bean>
- </beans>
(3)test类:
- package com.wzj.test;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import com.wzj.entity.Student;
- public class Test {
- public static void main(String[] args) {
- //通过ApplicationContext接口的实现类实例化Spring上下文对象
- ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
- //通过getBean()方法来获取到Student类的对象
- Student student=(Student)context.getBean("student");
- System.out.println(student);
- }
- }
三、Bean配置
1.BeanFactory和ApplicationContext
Spring框架提供了两种IOC容器的实现:(1)BeanFactory:IOC容器的基本实现
(2)ApplicationContext(推荐使用):提供了更多的高级特性,是BeanFactory的子接口
BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;
ApplicationContext 面向使用 Spring 框架的开发者,几乎所有的应用场合都直接使用 ApplicationContext 而非底层的 BeanFactory
ApplicationContext的实现类:
—— ClassPathXmlApplicationContext:从 类路径下加载配置文件
—— FileSystemXmlApplicationContext: 从文件系统中加载配置文件
2.配置Bean——基于xml文件的形式
(1)在spring配置文件中以<bean>元素来配置Bean实例,如:- <!--
- id:Bean的名称,在IOC容器中必须是唯一的,还可以指定多个名字,名字之间用英文逗号、分号或空格隔开
- class:Bean所对的类的全名,其实内部是通过反射来动态创建对象的
- -->
- <bean id="student" class="com.wzj.entity.Student">
- <!-- 为Student对象的属性赋值,value也可以作为子标签 -->
- <property name="id" value="1"/>
- </bean>
(2)获取bean实例:
- //getBean()的参数名称要和配置文件中bean的id对应
- Student student=(Student)context.getBean("student");
- Student student=context.getBean("student",Student.class);
3.依赖注入的方式:
Spring支持3中依赖注入的方式:—— 属性注入(最常用)
—— 构造器注入
—— 工厂方法注入(很少使用,不推荐)
(1)属性注入:
- <property name="name" value="张三"></property>
- <property name="name">
- <value>张三</value>
- </property>
(2)构造器注入:
①按索引匹配入参
- <bean id="student" class="com.wzj.entity.Student">
- <constructor-arg value="" index="0"></constructor-arg>
- </bean>
②按类型匹配入参
如果说类中不止有一个构造方法的时候,为了防止容器不知道调用哪个,可以为参数指定类型type(方法重载的区别不就是看参数的区别么)
- <constructor-arg value="" type=""></constructor-arg>
type和index可以混合使用
4.依赖注入不同的数据类型:
(1)注入直接量(基本数据类型、字符串)
直接在value属性中书写值,若包含特殊符号,可以使用一下方式转义:- <value><![CDATA[这里写值]]></value>
(2)引用其他bean组件
①引用外部已定义好的bean:创建Teacher类,Student类中包含Teacher的属性,配置:
- <bean id="teacher" class="com.wzj.entity.Teacher">
- <property name="id" value="3"/>
- <property name="name" value="张老师"/>
- </bean>
- <bean id="student" class="com.wzj.entity.Student">
- <!-- 使用ref属性引用其他bean,也可以作为子标签使用 -->
- <property name="teacher" ref="teacher" />
- </bean>
可以直接在属性中创建内部Bean,不能被外部引用
- <bean id="student" class="...">
- <property name="teacher">
- <bean class="...Teacher">
- <!-- 省略里面的配置-->
- </bean>
- </property>
- </bean>
(3)注入null和空字符串
①如果有时候想给实例的某些属性赋null值(当然,不赋值也是null值),这时候就可以使用到null值的特有标签<null/>- <property name="propertyName"><null/></property>
(4)为级联属性注入值
Student类中包含Teacher类的属性,此时可以再student的bean中为teacher属性的属性赋值,这种方式很少使用,也不建议使用- <bean id="student" class="com.wzj.entity.Student">
- <property name="teacher" ref="teacher"></property>
- <property name="teacher.name" value="张老师"></property>
- </bean>
(5)注入集合属性
①list
假如Teacher类中包含着一个List<Student> students属性,则此时就可以使用list标签- <bean id="teacher" class="com.wzj.entity.Teacher">
- <property name="students">
- <list>
- <ref bean="student1"/>
- <ref bean="student2"/>
- <ref bean="student3"/>
- </list>
- </property>
- </bean>
②Map
①使用entry作为map的子节点,假如在Teacher类中有一个Map<String,Student>类型的students属性- <property name="students">
- <map>
- <entry key="AA" value-ref="student1"></entry>
- <entry key="BB" value-ref="student2"></entry>
- <entry key="CC" value-ref="student3"></entry>
- </map>
- </property>
③java.util.Properties
- <property name="students">
- <props>
- <prop key="键">值</prop>
- <prop key="键">值</prop>
- </props>
- </property>
(6)在外部配置单利的List,供多个bean使用:
①导入命名空间:
xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation中添加:
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd
②使用util:list标签
- <util:list id="list">
- <!-- ref、value、或者内部Bean等使用方式 -->
- </util:list>
5.使用p命名空间简化配置
使用p空间可以简化配置文件,需导入命名空间:xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation中添加:
http://www.springframework.org/schema/p
http://www.springframework.org/schema/p/spring-p-4.0.xsd
使用:
- <bean id="student" class="com.wzj.entity.Student" p:name="name值" p:teacher-ref="teach引用"></bean>
6.自动装配
spring IOC容器可以为我们自动装配,只需要在bean的autowire属性里指定自动装配模式(1)byType(根据类型自动装配):
若 IOC 容器中有多个与目标 Bean 类型一致的 Bean. 在这种情况下, Spring 将无法 判定哪个 Bean 最合适该属性, 所以不能执行自动装配.(2)byName(根据名称自动装配):
必须将目标 Bean 的名称和属性名设置的完全相同.(3)constructor(通过构造器自动装配):
当 Bean 中存在多个构造器时, 此种自动装配方式将会很复杂. 不推荐使用例:<bean autowire="byName">..</bean>
7.Bean之间的关系
继承、依赖关系,但是这种关系不是面向对象中的继承,是配置之间的继承(1)继承
①可以使用Bean元素的parent属性指定其父Bean,则其成为子Bean
②子Bean可以继承父Bean的配置,也可以覆盖父Bean的配置
③父Bean也可以作为一个模板,使用abstract="true"设置,此时这个父Bean不能被实例化,只能当配置模板被继承(类似于Java中的抽象类)
④如果说一个bean的class属性没有设置,那么这个bean必须是一个模板bean(即abstract为true)
⑤不是父Bean所有的属性子Bean都能继承,比如:abstract="true",autowire等
(2)依赖
1.spring可以通过depends-on属性指定这个bean依赖的bean,如果说spring配置中不存在被依赖的bean,则初始化这个Bean的时候就会报错。
2.如果前置依赖于多个Bean,则可以通过逗号、空格的方式配置Bean的名称。
8.Bean的作用域
使用Bean元素的scope属性来配置作用域
(1)singleton:默认值,容器初始化时创建实例,在整个生命周期中只创建一个实例,单例!
(2)prototype:原型的,容器初始化时不创建实例,而在每次使用getBean的时候都创建一个新的实例、
(3)request:没次Http请求时都创建一个新的Bean,该作用域仅作用域WebApplicationContext环境
(4)session:同一个HttpSession共用一个Bean,不同的session使用不用的Bean
9.使用外部属性文件:
有时需要在 Bean 的配置里混入系统部署的细节信息(例如: 文件路径, 数据源配置信息等). 而这些部署细节实际上需要和 Bean 配置相分离;Spring 提供了一个PropertyPlaceholderConfigurer 的 BeanFactory 后置处理器使用方式:
(1)创建一个属性文件,比如db.properties:
- driverclass=oracle.jdbc.OracleDriver
- url=jdbc:oracle:thin:@localhost:1521:orcl
- username=scott
- password=tiger
- <!--导入属性文件-->
- <context:property-placeholder location="classpath:db.properties"/>
然后使用的时候使用${var}的方式:
- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
- <!-- 指定驱动类 -->
- <property name="driverClassName" value="${driverclass}"/>
- </bean>