Spring中Bean的生命周期
1. Bean的生命周期
Spring中Bean的生命周期分为两种
- Bean创建的生命周期
- Bean销毁的生命周期
1.1 Bean的创建生命周期
要想搞清楚Bean的生命周期,我们首先需要对Bean对象有清晰的了解
1. Bean对象和普通对象
UserService userService = (UserService)applicationContext.getBean("userService");
从中获取的就是Bean对象
UserService userService = new UserService();
使用new的方式,构建出来的就为普通对象
2. Bean的创建流程
我们都知道对象的创建都是依靠构造方法进行创建的,Spring也不例外,所以我们能得出一下流程
我们的UserService Bean对象是通过
UserService类—->得到无参构造方法—->获取到普通对象—->经过一系列处理—->Bean对象
那么要想知道在普通对象和Bean对象之间,进行了那些操作,我们可以再详细看一看
//先创建OrderService类
@Component
public class OrderService {
}
//再创建UserService类
@Component
public class UserService {
@Autowired
private OrderService orderService;
public void test() {
System.out.println(orderService);
}
}
//在Test打印输出
public class Test {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService)applicationContext.getBean("userService");
userService.test();
UserService userService1 = new UserService();
userService1.test();
}
}
结果为
com.zhn.service.OrderService@647fd8ce
null
可见,普通对象和Bean对象中,区别就是,属性有没有值
也就是说
普通对象经过依赖注入后,便可以得到Bean对象
3. Spring如何进行依赖注入
Spring创建对象后,会扫描该类属性中,有没有@Autowired或者@Resource注解,如果有,spring就会给该属性赋值
那么是从哪里找呢,实际上,在Spring创建完Bean对象后,都会将它放入使用Map构建的单例池中(Map<beanName,Bean对象>
),等到下一次调用会先从该Map池中寻找相应的Bean(查找方式:先按照类型匹配Bean,再按照名字寻找Bean),如果有,则会直接拿到使用,如果没有则会重走下面的步骤:
UserService类—->得到无参构造方法—->获取到普通对象—->依赖注入—->????—->Bean对象—->放入Map中(Map<beanName,Bean对象)单例池
当Bean被放入单例池中以后,才能真正的被称为Bean对象
代码也可以直接使用该方式,创建Bean对象
Object o = new UserService();
applicationContext.getBeanFactory().registerSingleton("xxx",o);
创建一个beanName为xxx的,Object o的Bean对象
4. 底层源码实现
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "Bean name must not be null");
Assert.notNull(singletonObject, "Singleton object must not be null");
synchronized (this.singletonObjects) {
Object oldObject = this.singletonObjects.get(beanName);
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
//添加Bean
addSingleton(beanName, singletonObject);
}
}
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
//将Bean put到Map中
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
//Map结构
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
5.Bean中的方法,Spring如何管理
需要在类中实现InitializingBean这个接口,重写afterPropertiesSet(),则Spring会在Bean初始化完成之前,调用该方法
@Component
public class UserService implements InitializingBean {
@Autowired
private OrderService orderService;
public void test() {
System.out.println(orderService);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Spring处理的方法执行了");
}
}
再次执行下面代码
public class Test {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService)applicationContext.getBean("userService");
userService.test();
System.out.println("---------------分割线------------------");
UserService userService1 = new UserService();
userService1.test();
}
}
结果
Spring处理的方法执行了
com.zhn.service.OrderService@291ae
—————分割线——————
null
可见仍旧只有Bean对象才会执行该方法
那么Bean的创建流程可以完善为
UserService类—->得到无参构造方法—->获取到普通对象—->依赖注入—->afterPropertiesSet()—->Bean对象—->放入Map中(Map<beanName,Bean对象)单例池
那么afterPropertiesSet()过程是如何判断,Bean需不需要执行函数呢?
使用bean instance of InitializingBean,判断是否实现该接口
如果实现该接口,则对bean进行强制转化,执行afterPropertiesSet()
((InitializingBean)bean).afterPropertiesSet()
完成了Bean的初始化
6. Bean初始化后(AOP)
Bean的流程完善为
UserService类—->得到无参构造方法—->获取到普通对象—->依赖注入—->afterPropertiesSet()—->初始化后(AOP)—->代理对象—->Bean对象—->放入Map中(Map<beanName,Bean对象)单例池
AOP后 Bean对象到底是一个什么对象
代理对象?
还是Bean的普通对象?
举例
//被代理对象
@Component
public class UserService {
@Autowired
private OrderService orderService;
public void test() {
System.out.println(orderService);
}
}
//一般逻辑
//代理对象
class UserServiceProxy extends UserService
{
public void test(){
//执行切面逻辑
super.test();
//打印出来为null
}
}
//Spring逻辑
//代理对象
class UserServiceProxy extends UserService
{
UserService target;
public void test(){
//执行切面逻辑
//target.test() //Uservice普通对象.test() 打印orderService属性
//可以打印出来值
}
}
target存放的为依赖注入后的普通对象,orderService有值
代理对象UserServiceProxy OrderService无值
其中由于进行AOP,所以userService拿到的值应该为userService的代理对象
代理对象中OrderService值为空
点击运行后
zhnBefore
com.zhn.service.OrderService@3f1d2e23
—————分割线——————
OrderService又输出出来了值
说明 执行Test方法的为经过依赖注入后的普通对象,
AOP执行流程就很清楚了,先是代理对象执行重写的test方法,然后是进行AOP的增强操作,执行结束后,依赖注入后的普通对象再执行自身的test方法