您的位置:首页 > 编程语言 > Java开发

spring学习总结(七):IOC & DI 配置Bean之bean的生命周期及bean的配置方式

2016-11-26 17:36 1101 查看
IOC & DI 配置Bean之bean的生命周期及bean的配置方式

Bean的生命周期

IOC 容器中 Bean 的生命周期方法

Spring IOC 容器可以管理 Bean 的生命周期,
Spring 允许在 Bean 生命周期的特定点执行定制的任务.
在 Bean 的声明里设置 init-methoddestroy-method 属性, 为 Bean 指定初始化和销毁方法.

Car.java
package com.xyc.spring.cycle;

/**
*
* @ClassName:  Car
* @Description:Spring IOC容器及生命周期测试
* @author: xyc
* @date:   2016年11月26日 下午4:25:23
*
*/
public class Car {

private String brand;

public void setBrand(String brand) {
System.out.println("Car setBrand.........");
this.brand = brand;
}

public void init(){
System.out.println("Car init...........");
}

public void destory(){
System.out.println("Car destory..........");
}

public Car() {
System.out.println("Car Contruator...");
}

@Override
public String toString() {
return "Car [brand=" + brand + "]";
}

}


bean-cycle.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 
<!-- 在 Bean 的声明里设置 init-method 和 destroy-method 属性, 为 Bean 指定初始化和销毁方法. -->
<bean id="car" class="com.xyc.spring.cycle.Car" init-method="init" destroy-method="destory">
<property name="brand" value="BMW"></property>
</bean>

</beans>


ApplicationCycle.java

package com.xyc.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.xyc.spring.cycle.Car;

/**
*
* @ClassName:  ApplicationCycle
* @Description:测试spring IOC容器及生命周期
* @author: xyc
* @date:   2016年11月26日 下午4:30:05
*
*/
public class ApplicationCycle {

public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean-cycle.xml");

Car car = (Car) context.getBean("car");

System.out.println(car);

//关闭IOC
context.close();
}

}


运行结果:



由此可以看出,Spring IOC 容器对 Bean 的生命周期进行管理的过程如下:

通过构造器或工厂方法创建 Bean 实例
为 Bean 的属性设置值和对其他 Bean 的引用
调用 Bean 的初始化方法
Bean 可以使用了
当容器关闭时, 调用 Bean 的销毁方法

添加 Bean 后置处理器后 Bean 的生命周期

Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理.
Bean 后置处理器对 IOC 容器里的所有 Bean 实例逐一处理, 而非单一实例. 其典型应用是: 检查 Bean 属性的正确性或根据特定的标准更改 Bean 的属性.
对Bean 后置处理器而言, 需要实现 BeanPostProcessor接口. 在初始化方法被调用前后, Spring 将把每个 Bean 实例分别传递给BeanPostProcessor接口的两个方法:



MyBeanPostProcessor.java
package com.xyc.spring.cycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
*
* @ClassName:  MyBeanPostProcessor
* @Description: Bean 后置处理器
* @author: xyc
* @date:   2016年11月26日 下午4:47:11
*
*/
public class MyBeanPostProcessor implements BeanPostProcessor {

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

if("car".equals(beanName)){
System.out.println("postProcessBeforeInitialization: "+bean+"@"+beanName);
}
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization: "+bean+"@"+beanName);

Car car = new Car();
car.setBrand("SUV");
return car;
}

}


xml中配置:
<!--
实现BeanPostProcessor接口,并具体提供
Object postProcessBeforeInitialization(Object bean, String beanName)  init-method之前被调用
Object postProcessAfterInitialization(Object bean, String beanName)   init-method之后被调用

bean: bean实例本身
beanName: IOC 容器中配置bean的id
返回值:是具体返回给用户的那个Bean,注意可以在以上两个方法中修改返回的Bean,甚至可以返回一个全新的bean
-->
<!-- 配置bean的后置处理器:不需要配置id,IOC容器自动识别一个BeanPostProcessor -->
<bean class="com.xyc.spring.cycle.MyBeanPostProcessor"></bean>


运行结果:



由此可以看出,Spring IOC 容器对 Bean 的生命周期进行管理的过程:

通过构造器或工厂方法创建 Bean 实例
为 Bean 的属性设置值和对其他 Bean 的引用
将 Bean 实例传递给 Bean 后置处理器的 postProcessBeforeInitialization 方法
调用 Bean 的初始化方法
将 Bean 实例传递给 Bean 后置处理器的 postProcessAfterInitialization方法
Bean 可以使用了
当容器关闭时, 调用 Bean 的销毁方法

Bean的配置方式

通过全类名(反射),通过反射的方式加载类的全路径,前面一直是这种方式.
通过工厂方法(静态工厂方法 & 实例工厂方法)
FactoryBean

通过调用静态工厂方法创建 Bean

调用静态工厂方法创建 Bean是将对象创建的过程封装到静态方法中. 当客户端需要对象时, 只需要简单地调用静态方法, 而不同关心创建对象的细节.
要声明通过静态方法创建的 Bean, 需要在 Bean 的 class 属性里指定拥有该工厂的方法的类, 同时在 factory-method 属性里指定工厂方法的名称. 最后, 使用 <constrctor-arg> 元素为该方法传递方法参数.

car.java
package com.xyc.spring.factory;

/**
*
* @ClassName:  Car
* @Description:Bean的配置方式
* @author: xyc
* @date:   2016年11月27日 下午5:06:21
*
*/
public class Car {

private String brand;

private Double price;

public String getBrand() {
return brand;
}

public void setBrand(String brand) {
this.brand = brand;
}

public Double getPrice() {
return price;
}

public void setPrice(Double price) {
this.price = price;
}

public Car(String brand, Double price) {
this.brand = brand;
this.price = price;
}

public Car() {
}

@Override
public String toString() {
return "Car [brand=" + brand + ", price=" + price + "]";
}

}


CarStaticFactory.java
package com.xyc.spring.factory;

import java.util.HashMap;
import java.util.Map;

/**
*
* @ClassName:  CarStaticFactory
* @Description:静态工厂方法:直接调用某一个类的静态方法就可以返回Bean实例
* @author: xyc
* @date:   2016年11月27日 下午5:09:22
*
*/
public class CarStaticFactory {

private static Map<String,Car> map = new HashMap<String, Car>();

static{
map.put("BYD", new Car("BYD", 300000.00));
map.put("BMW", new Car("BMW", 500000.00));
}

public static Car getCar(String brand){
return map.get(brand);
}
}


xml中配置
<!-- 通过静态工厂的方式来配置bean,注意不是配置静态工厂方法实例,而是配置bean实例 -->
<!--
class: 指向静态工厂方法的全类名
factory-method:指向静态工厂方法的名字
constructor-arg:如果工厂方法需要传入参数,则使用constructor-arg 来配置参数
-->
<bean id="car1" class="com.xyc.spring.factory.CarStaticFactory" factory-method="getCar">
<constructor-arg value="BMW"></constructor-arg>
</bean>


通过调用实例工厂方法创建 Bean

实例工厂方法: 将对象的创建过程封装到另外一个对象实例的方法里. 当客户端需要请求对象时, 只需要简单的调用该实例方法而不需要关心对象的创建细节.
要声明通过实例工厂方法创建的 Bean

--在 bean 的 factory-bean 属性里指定拥有该工厂方法的 Bean
--在 factory-method 属性里指定该工厂方法的名称
--使用 construtor-arg 元素为工厂方法传递方法参数

CarInstanceFactory.java
package com.xyc.spring.factory;

import java.util.HashMap;
import java.util.Map;

/**
*
* @ClassName:  CarInstanceFactory
* @Description:实例工厂方法:实例工厂的方法,即现需要创建工厂本身,再调用工厂的实例来返回bean 的实例
* @author: xyc
* @date:   2016年11月27日 下午5:22:00
*
*/
public class CarInstanceFactory {

private Map<String,Car> map;

public CarInstanceFactory() {
map = new HashMap<String, Car>();
map.put("BYD", new Car("BYD", 300000.00));
map.put("BMW", new Car("BMW", 300000.00));
}

public Car getCar(String brand){
return map.get(brand);
}
}


xml中配置:
<!-- 配置工厂实例 -->
<bean id="carInstanceFactory" class="com.xyc.spring.factory.CarInstanceFactory"></bean>

<!-- 通过实例工厂配置bean -->
<!--
factory-bean:指向实例工厂id
factory-method:指向实例工厂方法的名字
constructor-arg:如果工厂方法需要传入参数,则使用constructor-arg 来配置参数
-->
<bean id="car2" factory-bean="carInstanceFactory" factory-method="getCar">
<constructor-arg value="BYD"></constructor-arg>
</bean>



实现 FactoryBean 接口在 Spring IOC 容器中配置 Bean

Spring 中有两种类型的 Bean,
一种是普通Bean, 另一种是工厂Bean, 即FactoryBean.
工厂 Bean 跟普通Bean不同, 其返回的对象不是指定类的一个实例, 其返回的是该工厂 Bean 的 getObject 方法所返回的对象

CarBeanFactory.java
package com.xyc.spring.factory;

import org.springframework.beans.factory.FactoryBean;

/**
*
* @ClassName:  CarBeanFactory
* @Description:通过FactoryBean工厂创建bean
* @author: xyc
* @date:   2016年11月27日 下午5:46:52
*
*/
public class CarBeanFactory implements FactoryBean<Car>{

private String brand;

public void setBrand(String brand) {
this.brand = brand;
}

/**
*
* <p>Title: getObject</p>
* <p>Description: </p>
* @return 返回bean的对象
* @throws Exception
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
@Override
public Car getObject() throws Exception {
return new Car(brand, 300000.00);
}

/**
*
* <p>Title: getObjectType</p>
* <p>Description: </p>
* @return   bean类型
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
@Override
public Class<?> getObjectType() {
return Car.class;
}

/**
*
* <p>Title: isSingleton</p>
* <p>Description: </p>
* @return   是否单例
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
@Override
public boolean isSingleton() {
return true;
}
}


xml中配置:
<!-- 通过FactoryBean工厂配置Bean的实例
class:指向FactoryBean的实现类的全类名
property:指向FactoryBean的实现类的属性

实际返回的是FactoryBean 的getObject()方法返回的实例
-->
<bean id="car3" class="com.xyc.spring.factory.CarBeanFactory">
<property name="brand" value="BMW"></property>
</bean>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: