【 Spring IoC Container 使用步骤 (非Web环境) 】
1、Configuration metadata
可以使用 XML 文件,比如 container.xml
可以使用注解
2、创建容器:
// 在 指定配置文件时可以使用 Ant 风格的通配符
final String configLocations = "classpath:org/**/container.xml";
ApplicationContext container = new ClassPathXmlApplicationContext( configLocations ) ;
ApplicationContext 是个接口
final String configLocations = "classpath:org/**/container.xml";
AbstractApplicationContext container = new ClassPathXmlApplicationContext(configLocations) ;
AbstractApplicationContext 是个抽象类,其中定义了 close() 方法
3、从容器中获取 Bean
ClassName x = container.getBean( "bean-id" , ClassName.class ) ;
其中 bean-id 是指 XML 文件中 或 注解中 为 Bean 指定的 id
其中 ClassName 是指 Bean 的类型,比如 org.malajava.container.Person
4、关闭容器 (优秀是一种习惯)
container.close() ; // AbstractApplicationContext 是个抽象类,其中定义了 close() 方法
【 控制反转 ( Inversion of Control , IoC ) 】
使用一个 Person 类型的对象:
[ Java ]
Date date = new Date();
Person p = new Person();
p.setId( 9527 ) ;
p.setName( "华安" );
p.setGender( '男' );
p.setBirthdate( date ) ; // 引用另外一个对象
System.out.println( p.getId() + " : " + p.getName() + " , " + p.getGender() );
[ IoC ]
<bean id="date" class="java.util.Date" />
<bean id="person" class="org.malajava.container.Person">
<property name="id" value="9527" />
<property name="name" value="华安" />
<property name="gender" value="男" />
<property name="birthdate" ref="date" />
</bean>
Person p = container.getBean( "person" , Person.class );
System.out.println( p.getId() + " : " + p.getName() + " , " + p.getGender() );
【 依赖注入 ( Dependency Injection , DI ) 】
1、基于 setter 的注入方式 ( Spring 支持 ) [主要应用方向]
对于"简单类型"来说可以使用以下形式注入:
<property name = "属性名" value = "字面量" />
或
<property name="属性名" >
<value>字面量</value>
</property>
所谓"简单类型"是指:
8种基本数据类型及其包装类类型的属性
byte --> Byte
short ---> Short
int ---> Integer
long --> Long
float ---> Float
double ---> Double
char ----> Character
boolean ---> Boolwan
java.lang.String
对于其他的引用类型的属性来说,要使用以下形式注入:
<property name = "属性名" ref = "所引用的Bean的id" />
或
<property name="属性名" >
<ref bean="所引用的Bean的id" />
</property>
Spring Framework 3.x 开始支持 p 命名空间 ( namespace ):
首先需要在 xml 文件中引入 p 命名空间:
xmlns:p="http://www.springframework.org/schema/p"
对于 "简单类型" 的属性来说,可以使用以下形式注入:
<bean id="...." class="...." p:属性名 = "属性值" />
对于其他的引用类型的属性来说,要使用以下形式注入:
<bean id="...." class="...." p:属性名-ref = "属性值" />
2、基于构造方法的注入方式 ( Spring 支持 )
<bean id="student" class="org.malajava.injection.Student" >
<constructor-arg name="name" value="郭襄" />
<constructor-arg name="id" value="1" />
<constructor-arg name="number" value="1003" />
<constructor-arg name="gender" value="女" />
<constructor-arg name="birthdate" ref="date" />
<constructor-arg name="married" value="false" />
</bean>
注意:
a>、如果一个类中提供了带参数的构造方法,建议创建不带参数的那个构造方法
b>、在使用 constructor-arg 时,可以使用 index 、type 、name 来确定为那个参数注入值
c>、对于 "简单类型" 来说,使用 value 属性即可注入相应值;
对于其他引用类型来说使用 ref 属性引用容器中已经声明的其他Bean的id
3、基于接口方式的注入( Spring 默认不支持 )
【 Bean 的创建方式 ( bean creation ) 】
1、使用构造方法创建 Bean 实例
比如:
使用无参构造:
<bean id="date" class="java.util.Date" />
使用带参数的构造:
<bean id="student" class="org.malajava.injection.Student" >
<constructor-arg name="name" value="郭襄" />
<constructor-arg name="id" value="1" />
<constructor-arg name="number" value="1003" />
<constructor-arg name="gender" value="女" />
<constructor-arg name="birthdate" ref="date" />
<constructor-arg name="married" value="false" />
</bean>
2、静态工厂方法
public class Car {
private String brand ;
public static Car getInstance() {
System.out.println( "Car.getInstance()" );
Car c = new Car();
return c ;
}
}
<bean id="car"
class="org.malajava.creation.Car"
factory-method="getInstance"
p:brand="BYD" />
<bean id="calendar"
class="java.util.Calendar"
factory-method="getInstance" />
3、实例工厂方法
public class Bus {
private String brand ;
}
public class BusFactory {
public Bus create() {
Bus b = new Bus();
b.setBrand( "比亚迪" );
return b ;
}
}
<bean id="busFactory" class="org.malajava.creation.BusFactory" />
<bean id="bus" class="org.malajava.creation.Bus" factory-bean="busFactory" factory-method="create" >
<property name="brand" value="比亚迪" />
</bean>
4、FactoryBean
a>、需要有一个类实现了 org.springframework.beans.factory.FactoryBean 接口(并实现其中的抽象方法)
并指定 该实现类所创建的 对象的类型 (在类型参数中指定)
public class ShipFactoryBean implements FactoryBean<Ship>{
@Override
public Ship getObject() throws Exception { // 负责创建 Ship 类型的对象
return null;
}
@Override
public Class<?> getObjectType() { // 返回 所创建对象的类型
return null;
}
}
b>、在 FactoryBean 实现类内部的 getObject 方法用来创建 <T> 类型的对象
<!-- 如果 class 所制定的 类 实现了 FactoryBean 接口,
那么 这个配置所创建的对象 是由 该 FactoryBean 实现类的 getObject 方法所返回的对象 -->
<bean id="ship" class="org.malajava.creation.ShipFactoryBean" />