# bean 生命周期

## bean的生命周期图示

bean 的生命周期和 容器行为 可以用下图进行表示：

![](https://raw.githubusercontent.com/chesterzhang/intro_Java/zhc_dev/picture/spring_ioc/bean_life.drawio.png)

其中 init-method 并不是一个具体的方法名字，而是一个参数，可以将 init-method 指向类中的方法，该方法会在为对象注入属性以后调用。

## 案例演示：

假设有这么一个 Order 类， 需要计算 total=price\*quantitive。同时我们在 构造方法, setter 方法 上做了输出，用来观察 bean的生命周期。将 calTotal 方法 设置为 bean的 init-method， destroy 方法设置为 bean的 idestroy-method, 以便观察 bean 的生命周期。

```java
public class Order {
    private  Float price;
    private Integer quantity;
    private Float total;

    public Order(){
        System.out.println("创建 Order 对象 : "+ this);
    }

    public void calTotal(){
        System.out.println("执行 calTotal 方法 ");
        total = price * quantity;
    }

    public void destroy(){
        System.out.println("订单销毁方法");
    }

    public void pay(){
        System.out.println("支付订单金额为 : "+total);
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        System.out.println("setPrice 方法");
        this.price = price;
    }

    public Integer getQuantity() {
        return quantity;
    }

    public void setQuantity(Integer quantity) {
        System.out.println("sestQuantitive 方法");
        this.quantity = quantity;
    }

    public Float getTotal() {
        return total;
    }

    public void setTotal(Float total) {
        this.total = total;
    }
}

```

如果每次调用都需要计算则会冗余。这时在 applicationContext.xml 文件中将 bean的 inti-method 指向 Order 类中的 calTotal 方法，则会在注入属性后调用。类似地，bean的 destroy 方法也指向 Order 类中的 destroy 方法。

```xml
 <!-- init-method 方法 会在 设置完属性以后再被调用, destroy-method 方法会在 Ioc 容器销毁之前调用 -->
<bean id="order1" class="indi.chester.spring.ioc.entity.Order" init-method="calTotal" destroy-method="destroy">
    <property name="price" value="19"/>
    <property name="quantity" value="1000"/>
</bean>
```

### 测试一下

```java
public class SpringApplication2 {
    public static void main(String[] args) {

        //创建 Spring IoC 容器, 并配置文件在容器中实例化对象
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

        Order order = context.getBean("order1",Order.class);
        order.pay();

        //销毁容器
        ((ClassPathXmlApplicationContext) context).registerShutdownHook();

    }

}
```

### 运行结果

```html
创建 Order 对象 : indi.chester.spring.ioc.entity.Order@97e1986
setPrice 方法
sestQuantitive 方法
执行 calTotal 方法 
支付订单金额为 : 19000.0
订单销毁方法

```
