标准化的Markdown文本通常会包含以下内容:
标题
子标题
次级子标题
正文内容
- 列表项1
- 列表项2
-
列表项3
-
数字列表项1
- 数字列表项2
- 数字列表项3
代码块如下:
这里是代码块
int a = 1;
String str = "hello";
System.out.println(str);
以下是“Spring Bean生命周期源码原理图解”的完整攻略:
Spring Bean生命周期源码原理图解
概述
Spring作为一个典型的IOC(Inversion of Control,控制反转)框架,它的核心就是Bean容器的管理。对于每个Spring Bean,它会经历Bean的加载、实例化、属性注入、初始化、销毁等一系列的生命周期过程。了解Spring Bean生命周期的过程以及源码原理是我们深入学习Spring框架的前提。
Spring Bean的生命周期
Bean定义的加载和解析
Bean定义的加载和解析最终都会调用到BeanDefinitionRegistry的registerBeanDefinition方法,该方法的作用是用BeanDefinition向容器注册Bean,并将BeanDefinition放入一个名为beanDefinitionMap的缓存中。
Bean的实例化
Bean实例化的操作是通过BeanDefinition创建对应的实例对象,这个过程发生在BeanFactory的getBean方法中。
public Object getBean(String name) throws BeansException {
return getBean(name, (Object[]) null);
}
其中,name参数对应的就是Bean的id,如果Bean还没有被实例化,则会首先进行实例化. Bean实例化的过程通过DefaultSingletonBeanRegistry的getSingleton进行管理。getSingleton方法首先会从singletonObjects缓存中获取对应的单例对象,如果没有获取到,则会首先进行BeanDefinition的实例化操作,最终将实例化后的Bean对象缓存到singletonObjects中。
Bean的依赖注入
在Bean实例化完成之后,Spring会首先进行Bean的属性注入操作。属性注入是Spring IOC容器最核心的功能之一。对于注入依赖的方式,我们平时使用的最多的就是Setter注入和Constructor注入两种方式。
Setter注入:
@Component
public class UserServiceImpl implements UserService{
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
}
Constructor注入:
@Component
public class UserServiceImpl implements UserService{
private UserDao userDao;
public UserServiceImpl(UserDao userDao){
this.userDao = userDao;
}
}
Bean的初始化
Bean的初始化操作主要是为了解决Bean在实例化后,其属性仍然处于未赋值状态的问题。Bean的初始化操作分为两个阶段:afterPropertiesSet和init-method。其中,afterPropertiesSet方法是在Bean实例化后、属性注入完成之后被调用的,如果Bean实现了InitializingBean接口,则afterPropertiesSet方法会被调用。
Init-method方法是在相对独立的方法中定义的,是为了让开发人员有机会在Bean初始化的过程中加入额外的逻辑处理。
Bean的销毁
Bean的销毁是生命周期的最后一个阶段。在销毁Bean之前,需要先完成对Bean的某些操作,比如资源关闭等。Bean的销毁操作是通过DisposableBean接口中的destroy方法来实现的。如果一个Bean定义了destory-method方法,则其会被调用。
示例说明
示例1:Setter注入
下面是一个基于Setter注入方式的示例:
@Component
public class UserServiceImpl implements UserService{
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
}
在上述代码中,UserServiceImpl中的UserDao对象是通过定义setUserDao方法来进行注入的。
示例2:Init-method
下面是一个使用了Init-method的示例:
@Component
public class User {
private String name;
public void setName(String name) {
this.name= name;
}
public void init() {
System.out.println("User has been initialized");
}
}
在上述代码中,我们定义了init()方法,并在类的注解中使用了initMethod="init"来声明使用的初始化方法。在初始化的过程中,会输出"User has been initialized"。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Bean生命周期源码原理图解 - Python技术站