一、IOC与DI
IOC:控制反转,spring容器主动将bean对象推送给管理组件。传统的JAVA中,两个对象之间的关系是有一个对象来管理另一个对象,但是在spring中,对象之间的关系已经由容器确定好,无需手动设置两个对象之间的关系。
DI:依赖注入,组件预先以定义好的方式接收容器推送的bean对象。
二、spring容器
容器依然必须由程序进行实例化(初始化)。初始化IOC容器有两种方式:BeanFactory和ApplicationContext。
ApplicationContext主要有两个实现类:
ClassPathXmlApplicationContext类:从类路径下加载配置文件applicationContext.xml
FileSystemXmlApplicationContext类:从文件系统中加载配置文件applicationContext.xml
ApplicationContext在初始化上下文时,只实例化配置文件中所有的单实例Bean。
三、bean配置
1.通过settter方法注入(将值spring通过property属性的方式注入helloworld对象的Name属性中,是通过反射调用类HelloWord的setName方法。
<!--
class:bean的全类名,spring通过反射的方式在容器中创建bean,所以bean中必须要有无参的构造器
id: 标识一个容器创建的对象,且在容器中,该id唯一。程序中通过id属性值来引用该bean。
-->
<bean id="helloworld" class="com.spring.beans.HelloWorld">
<property name="name" value="spring"></property>
</bean>
2.构造方法注入
!--
通过类的构造方法配置bean的属性
constructor-arg用于配置构造函数中传入的参数,
index:指定配置的是构造函数中的第几个参数,从0开始,0匹配给构造函数中第一个参数。如果不指定,默认为先配置的匹配给构造函数中前面的参数。
注意index="0" 中的0前后必须打引号,否则报错。index可以只指定部分,指定部分时,后面的参照默认情况排列。
type:用于指定该参数赋值的类型,可以区分重载的构造器。
-->
<bean id="car" class="com.spring.beans.Car">
<constructor-arg value="Audi" index="0"></constructor-arg>
<!-- 如果字面值包含特殊字符,可以使用<![CDATA[]]>包裹起来 -->
<constructor-arg><value><![CDATA[<Shanghai^>]]></value></constructor-arg>
<constructor-arg value="300000"></constructor-arg>
<!-- 属性值可以使用<value>子节点进行配置。 -->
<constructor-arg type="double"><value>240</value></constructor-arg>
</bean>
3.引用其他bean
<!-- bean需要相互引用时,使用ref属性,或ref元素 -->
<bean id="person" class="com.spring.beans.Person">
<property name="name" value="Tom"></property>
<property name="age" value="24"></property>
<!-- ref属性引用id为"car"的bean -->
<property name="car" ref="car"></property>
<!-- ref元素引用id为"car"的bean -->
<property name="car2">
<ref bean="car"/>
</property>
<!-- 内部bean -->
<property name="car3">
<bean class="com.spring.beans.Car">
<property name="brand"><value>Ford</value></property>
<property name="corp"><value>Changan</value></property>
<property name="price"><value>230000.0</value></property>
<property name="maxSpeed" value="200"></property>
</bean>
</property><!--赋值为null -->
<property name="car4"><null/></property>
</bean>
4.为bean的级联属性赋值
<bean id="person2" class="com.spring.beans.Person">
<constructor-arg value="zhangsan"></constructor-arg>
<constructor-arg value="28"></constructor-arg>
<!-- 在引用bean时,给bean级联赋值 -->
<constructor-arg ref="car"></constructor-arg>
<property name="car.maxSpeed" value="250"></property>
</bean>
5.为list集合赋值
<bean id="person3" class="com.spring.beans.collection.Person">
<property name="name" value="Mike"></property>
<property name="age" value="23"></property>
<property name="cars">
<list>
<ref bean="car"/>
<bean class="com.spring.beans.Car">
<property name="brand"><value>Ford</value></property>
<property name="corp"><value>Changan</value></property>
<property name="price"><value>230000.0</value></property>
<property name="maxSpeed" value="200"></property>
</bean>
</list>
</property>
</bean>
6.为map集合赋值
<!-- 配置map属性值 -->
<bean id="newperson" class="com.spring.beans.collection.NewPerson">
<property name="name" value="Rose"></property>
<property name="age" value="18"></property>
<property name="cars">
<map>
<entry key="car1" value-ref="car"></entry>
<entry key="car2" value-ref="car"></entry>
</map>
</property>
</bean>
7.为Properties赋值
<!-- 配置properties属性值 -->
<bean id="dataSource" class="com.spring.beans.collection.DataSource">
<property name="properties">
<props>
<prop key="user">root</prop>
<prop key="password">1234</prop>
<prop key="jdbcUrl">jdbc:mysql:///test</prop>
<prop key="driverClass">com.mysql.jdbc.Driver</prop>
</props>
</property>
</bean>
8.配置独立的集合bean,以供其他的bean共用
1)在applicationContext.xml文件中引入util命名空间
2)配置xml文件
<!-- 配置独立的集合bean,以供其他的bean共用 -->
<util:list id="cars">
<ref bean="car"/>
<ref bean="car2"/>
</util:list>
3)其他bean引用该独立的集合bean时,像引用其他bean一样使用
<bean id="person4" class="com.spring.beans.collection.Person">
<property name="name" value="Mike"></property>
<property name="age" value="23"></property>
<property name="cars" ref="cars"></property>
</bean>
9.p命名空间
<!--
spring2.5以后,可以引入p命名空间,为bean进行赋值。必须先参照上面的方式引入p命名空间。
-->
<bean id="person5" class="com.spring.beans.Person"
p:age="30" p:name="Queen" p:car-ref="car">
</bean>
10.bean之间的继承关系
<!--
bean属性的继承:
parent:该属性值指定bean的父bean,从父bean继承相应的属性值。
abstract:指定该bean是一个抽象bean,不能被实例化。只用来被继承配置,作为模板bean。
若某一个bean的class属性没有指定,则该bean必须是一个抽象bean。
-->
<bean id="address_parent"
p:city="Shanghai" p:street="beijing road" abstract="true">
</bean>
<bean id="address_child" class="com.spring.beans.relation.Address"
p:city="WuHan" parent="address_parent"></bean>
11.bean之间的依赖关系
<!-- bean依赖
depends-on:该属性用于指定该bean依赖于哪一个bean,只有在依赖的bean实例化后,才能实例化本bean。否则会报错。但不代表依赖的bean就被分配给被依赖的bean。多个依赖的bean可以通过逗号或者空格来指定多个需要依赖的bean。
-->
<bean id="person_car" class="com.spring.beans.relation.Car"
p:brand="Ford" p:corp="Shanghai" p:maxSpeed="240" p:price="300000"></bean>
<bean id="person" class="com.spring.beans.relation.Person"
p:name="zhangsan" p:age="12" p:address-ref="address_child" depends-on="person_car"></bean>
12.bean的作用域
<!--
默认情况下,bean为单例的,每次从上下文获取bean得到的都是同一个bean。可以通过scope进行设定。
scope属性有以下四种值:
singleton:单例,默认值,每次向容器获取bean时,都返回同一个bean。容器初始化时创建bean实例
prototype:原型,每次向容器获取bean时都产生一个新的bean。容器初始化时,不创建bean的实例。
request:WEB环境的作用域
session:WEB环境的作用域
-->
<bean id="car" class="com.spring.beans.relation.Car"
p:brand="Ford" p:corp="Shanghai" p:maxSpeed="240" p:price="300000" scope="request"></bean>
13.bean读取properties配置文件
1)在xml文件中导入context的命名空间
2)准备db.properties文件
3)配置xml配置文件
<!-- 导入属性文件 -->
<context:property-placeholder location="classpath:db.properties"/><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<property name="driverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"></property>
</bean>
4)使用bean
package com.spring.beans.properties;
import javax.sql.DataSource;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-properties.xml");
DataSource dataSource = (DataSource)ctx.getBean("dataSource");
System.out.println(dataSource);
}
}
14.使用工厂方法创建bean
1)编写工厂类
2)配置xml文件
<!--
工厂方法通过静态方法返回一个bean时,需要将class配置为工厂方法类,
并指定factory-method属性指定由哪一个方法得到bean。
需要使用constructor-arg元素传入输入的参数。
-->
<bean id="car" class="com.spring.beans.factory.StaticFactory" factory-method="getCar">
<constructor-arg name="name1" value="audi"></constructor-arg>
</bean><!--
动态工厂方法
需要先声明一个工厂类bean,再通过factory-bean和factory-method设置car bean的获取方式。
同样需要使用constructor-arg元素传入输入的参数。
-->
<bean id="carfactory" class="com.spring.beans.factory.DynamicFactory"></bean>
<bean id="car1" factory-bean="carfactory" factory-method="getCar">
<constructor-arg value="audi"></constructor-arg>
</bean>
15.通过FactoryBean来配置bean
1)定义自己的factorybean类,需要实现FactoryBean接口
2)配置xml文件
<!-- factorybean类的全类名设置为class的属性值。 -->
<bean id="car" class="com.spring.beans.factorybean.CarFactoryBean"></bean>