Bean 默认情况下是单例状态(singleton),所有人使用的都是同一个对象.
举例理解Bean的单例状态 :
假设现在有一个公共的 Bean,提供给 A 用户和 B 用户使用,然而在使用的途中 A 用户却“悄悄”地修改了公共 Bean 的数据,导致 B 用户在使用时发生了预期之外的逻辑错误 .
假设现在有一个IkunBean , 张三和李四和都要使用这个IkunBean .
Ikun.java
package Ikun;
public class Ikun {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Chicken{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
IkunBean
package com;
import Ikun.Ikun;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class IkunBean {
@Bean
public Ikun chicken() {
Ikun ikun = new Ikun();
ikun.setAge(26);
ikun.setName("鲲鲲");
return ikun;
}
}
Controller1.java
package com;
import Ikun.Ikun;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
/**
* 张三取出Bean对象
*/
@Controller
public class Controller1 {
@Autowired
private Ikun ikun;
public void docontroller1() {
System.out.println("张三取出该对象");
System.out.println("原数据:"+ ikun);
Ikun ikun1 = ikun;
ikun1.setName("只因");
System.out.println("现数据:"+ ikun1);
}
}
Controller2.java
package com;
import Ikun.Ikun;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
/**
* 李四取出Bean对象
*/
@Controller
public class Controller2 {
@Autowired
private Ikun ikun;
public void doController2() {
System.out.println("李四取出该对象");
System.out.println(ikun);
}
}
分析 :
总结 :
Bean作用域定义 : Bean对象在整个Spring中的某种行为模式 . 比如单例作用域表示的是Bean对象在Spring(框架)中只有一份 .
仍然是前面的例子 , 此处我们将Bean的作用域设置为多例模式 , 查看运行效果 . 设置多例模式的方法有以下两种 :
运行结果 :
BeanComponent.java
package com.component;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* 演示Bean的生命周期
*/
@Component
public class BeanComponent implements BeanNameAware {
//依赖注入
@Autowired
private UserComponent userComponent;
public BeanComponent(UserComponent userComponent) {
this.userComponent = userComponent;
userComponent.doComponent();
System.out.println("执行BeanComponent的构造方法!");
}
//继承 BeanNameAware接口,执行通知方法
public void setBeanName(String s) {
System.out.println("执行了setBeanName通知 : " + s);
}
//xml中init-method指定的方法
public void initMethod() {
System.out.println("执行了initMethod方法!");
}
@PostConstruct
public void myPostConstruct() {
System.out.println("执行了PostConstruct方法!");
}
//销毁前执行方法
@PreDestroy
public void myPreDestroy() {
System.out.println("执行了PreDestroy方法!");
}
//使用Bean
public void use() {
System.out.println("执行了use方法!");
}
}
Test5.java
import com.component.BeanComponent;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Bean的生命周期
*/
public class Test5 {
public static void main(String[] args) {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
BeanComponent component = (BeanComponent) context.getBean("beanComponent");
component.use();
context.destroy();
}
}
spring-config.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"
xmlns:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<content:component-scan base-package="com"></content:component-scan>
<bean id="beanComponent" class="com.component.BeanComponent"
init-method="initMethod"></bean>
</beans>
解释 :
Bean的生命周期类似于买房的过程 :
- 先买房(实例化 , 从无到有) ;
- 装修(设置属性) ;
- 买家电 (各种初始化) ;
- 入住(使用Bean) ;
- 卖出去(Bean销毁) .
Q : 为什么要先设置属性(依赖注入)再初始化呢 ?
A : 防止初始化时要用到依赖注入的对象 .
重点 : 掌握Bean的大的执行流程 .