Bean的配置一共有两种方式:一种是基于XML文件的方式,另外一种是基于注解的方式。
本文主要介绍基于XML文件的方式html
<bean id="helloWorld" class="com.sevenhu.domain.HelloWorld"> <property name="userName" value="Spring"></property> </bean>
上面的配置代码中:
id:Bean的名称,在IOC容器中必须是惟一的,若id,没有指定,那么Spring自动将类名做为Bean的名字,id能够指定多个名字,名字之间可用逗号,分 号,或空格分隔。
Spring容器
在Spring IOC容器读取Bean配置建立Bean实例以前,必须对它进行实例化,只有在容器实例化以后,才能够从IOC容器里获取Bean的实例并使用。
Spring提供了两种类型的IOC容器实现
-BeanFactory:Ioc容器的基本实现。
-ApplicationContext:提供了更多的高级特性。是BeanFactory的子接口。
-BeanFactory是Spring框架的基础设施,面向Spring自己;ApplicationContext面向使用Spring框架的开发者。
ApplicationContext主要有两个实现类:
-ClassPathXmlApplicationContext:从类路径下加载配置文件。
-FileSystemXmlApplicationContext:从文件系统中加载配置文件。
ApplicationContext在初始化上下文时就实例化全部单例的bean。
属性注入:
即经过setter方法注入bean的属性值或依赖的对象。属性注入使用<property>元素,使用name属性值指定bean的属性名称,value属性指定属性值。使用这种注入方式,那么bean中必须有一个默认的构造函数,即无参的构造函数。
java
eg: <property name="userName" value="Spring"></property>
构造方法注入:
按索引匹配入参:mysql
<bean id="car" class="com.sevenhu.domain.Car"> <constructor-arg value="长春一汽" index="0"></constructor-arg> <constructor-arg value="2000" index="1"></constructor-arg> <constructor-arg value="奥迪" index="2"></constructor-arg> </bean>
按类型匹配入参:spring
<bean id="car2" class="com.sevenhu.domain.Car"> <constructor-arg value="长春一汽" type="java.lang.String"></constructor-arg> <constructor-arg value="2000" type="double"></constructor-arg> <constructor-arg value="奥迪" type="java.lang.String"></constructor-arg> </bean>
注:字面值均可用字符串表示,能够经过<value>元素标签或value属性进行注入。基本数据类型及其封装类,String等类型均可以采用字面值注入的方 式。
若是一个bean的某一个属性是一个对象,可以使用以下配置:sql
<bean id="people" class="com.sevenhu.domain.People"> <property name="name" value="hujingwei"></property> <property name="car" ref="car2"></property> </bean>
或者使用内部类:session
<bean id="people1" class="com.sevenhu.domain.People"> <property name="name" value="zhangsongzhu"></property> <property name="car"> <!--内部bean,不能被外部的bean所引用,所以没有必要设置id--> <bean class="com.sevenhu.domain.Car"> <property name="brand" value="Ford"></property> <property name="creator" value="SomeOne"></property> <property name="price" value="100000"></property> </bean> </property> </bean>
可使用专用的<null/>元素标签为Bean的字符串或其它对象的属性值注入null值,以下:app
<bean id="people2" class="com.sevenhu.domain.People"> <property name="name" value="hu"></property> <!--若某一个bean的属性值须要设置为null--> <property name="car"><null/></property> </bean>
使用p命名空间:框架
为了简化XML文件的配置,愈来愈多的XML文件使用属性而非子元素配置信息,所以Spring自从2.5以后就引入了一个p命名空间,能够经过<bean>元素属性的方式配置Bean的属性dom
<!--使用p命名空间--> <bean id="people3" class="com.sevenhu.domain.People" p:name="seven" p:car-ref="car1"> </bean>
XML配置里的Bean自动装配ide
Spring IOC容器能够自动装配bean,须要作的仅仅是在<bean>的autowire属性中指定自动装配的模式,具体的装配模式以下:
-byType(根据类型装配):若IOC容器中有多个与目标bean类型一致的bean,在这种状况下,Spring将没法断定哪一个bean最适合该属性,因此不能进行自动装配。
-byName(根据名称自动装配):必须将目标bean的名称和属性名设置的彻底相同。
自动装配的缺点:在bean配置文件里设置autowire属性进行自动装配将会装配bean的全部属性,然而,若只但愿装配个别属性,autowire不够灵活;autowire属性要么根据类型装配,要么根据名称装配,不能二者兼而有之。
继承bean配置
Spring容许继承bean的配置,被继承的bean称为父bean,继承这个bean的bean为子bean。子bean从父bean中继承配置,包括bean的属性配置,子bean也能够覆盖从父bean继承过来的配置,父bean能够做为配置模版,也能够做为bean实例,若指向把父bean做为模版,能够设置bean的abstract属性为true,这样Spring就不会实例化这个bean。并非父bean中全部的属性都会被继承,好比:autowire,abstract等;也能够忽略父bean的class属性,让子bean指定本身的类,而共享相同的属性配置,可是此时abstract必须设为true。
<bean id="user" class="com.*.*"> <property name="userName" value="hu"/> </bean> <bean id="user1" parent="user"> <property name="userName" value="hu"/> </bean> <bean id="user2" parent="user"> <property name="userName" value="hu"/> </bean>
依赖bean配置:
Spring容许用户经过depends-on属性设定bean前置依赖的bean,前置依赖的bean会在bean实例化以前建立好,若是前置依赖多个bean,则能够经过逗号,空格的方式配置bean的名称。
<bean id="user3" depends-on="user1"> </bean>
bean的做用域(经过<bean>标签的scope属性设置)
-singleton 在Spring IOC容器中只存在一个bean实例,bean以单例的方式存在(默认的做用域)
-prototype 每次调用getBean()时都会返回一个新的实例
-request 每次HTTP请求都会返回一个新的bean,该做用域仅适用于WebApplicationContext环境中
-session 在session中共享一个bean,该做用域仅适用于WebApplicationContext环境中
使用外部属性文件:
首先外部文件db.properties的内容以下:
jdbc.user=root jdbc.password=1230 jdbc.driverClass=com.mysql.jdbc.Driver jdbc.jdbcUrl=jdbc:mysql:///test jdbc.initPoolSize=5 jdbc.maxPoolSize=10
那么在配置文件中配置以下:
<!-- 导入外部的资源文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 配置数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property> <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property> </bean>
IOC容器中Bean的生命周期
-经过构造器或工厂方法建立bean实例
-为bean的属性设置值和对其它bean的引用
-调用bean的初始化方法
-bean可使用了
-当容器关闭的时候,调用bean的销毁方法。
注:当bean的声明里设置init-method和destroy-method属性,为bean指定初始化和销毁方法(这两个方法通常都没有参数)
建立bean的后置处理器
bean后置处理器容许在调用初始化方法先后对bean进行额外的处理,bean后置处理器对IOC容器里全部bean实例逐一处理,而非单一实例。对bean的后置处理器而言,须要实现
Interface BeanPostProcessor接口,在初始化方法被调用先后,Spring将把每一个bean实例分别传递给BeanPostProcessor接口的如下两个方法:
postProcessorAfterInitialization(Object bean,String beanName); postProcessorBeforeInitialization(Object bean,String beanName);
添加后置处理器后Bean的生命周期
-经过构造器或工厂方法建立bean实例
-为bean的属性设置值和对其它bean的引用
-将bean实例传递给后置处理器的postProcessorBeforeInitialization(Object bean,String beanName);方法
-调用bean的初始化方法
-将bean实例传递给后置处理器的postProcessorAfterInitialization(Object bean,String beanName);方法
-bean可使用了
-当容器关闭的时候,调用bean的销毁方法。
代码以下:
package com.sevenhu.domain; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Created by hu on 2016/4/1. */ public class MyBean implements BeanPostProcessor { //该方法在bean的初始化方法以前调用 @Override public Object postProcessBeforeInitialization(Object o, String s) throws BeansException { //o就是bean实例对象,s就是bean实例的id System.out.println("before initialication ...."); //返回bean的实例对象 return o; } //该方法在bean的初始化方法以后调用 @Override public Object postProcessAfterInitialization(Object o, String s) throws BeansException { System.out.println("after initialication ...."); return o; } public static void main(String[] args){ ApplicationContext applicationContext=new ClassPathXmlApplicationContext("beans.xml"); } }
配置代码以下:
<!--配置bean后置处理器:不须要配置id属性,IOC容器会识别到它是一个bean后置处理器,并调用其方法--> <bean class="com.sevenhu.domain.MyBean"></bean>
经过调用静态工厂方法建立bean
调用静态工厂方法建立bean是将对象建立的过程封装到静态方法中,当客户端须要对象时,只须要简单地调用静态方法,而不关心建立对象的细节。
直接上代码,工厂以下:
<!-- 经过工厂方法的方式来配置 bean --> <!-- 1. 经过静态工厂方法: 一个类中有一个静态方法, 能够返回一个类的实例(了解) --> <!-- 在 class 中指定静态工厂方法的全类名, 在 factory-method 中指定静态工厂方法的方法名 --> <bean id="dateFormat" class="java.text.DateFormat" factory-method="getDateInstance"> <!-- 能够经过 constructor-arg 子节点为静态工厂方法指定参数 --> <constructor-arg value="2"></constructor-arg> </bean> <!-- 2. 实例工厂方法: 先须要建立工厂对象, 再调用工厂的非静态方法返回实例(了解) --> <!-- ①. 建立工厂对应的 bean --> <bean id="simpleDateFormat" class="java.text.SimpleDateFormat"> <constructor-arg value="yyyy-MM-dd hh:mm:ss"></constructor-arg> </bean> <!-- ②. 有实例工厂方法来建立 bean 实例 --> <!-- factory-bean 指向工厂 bean, factory-method 指定工厂方法(了解) --> <bean id="datetime" factory-bean="simpleDateFormat" factory-method="parse"> <!-- 经过 constructor-arg 执行调用工厂方法须要传入的参数 --> <constructor-arg value="1990-12-12 12:12:12"></constructor-arg> </bean>