-
Spring的出现就是为了更好的管理Bean,而IOC/DI/DL又是Spirng的核心,IOC在Spring中可以简单的理解为一个Map容器,帮我们管理控制着Bean的生命周期。
-
IOC -Inversion of control:控制反转,不是什么技术,而是一种设计思想,把对象的使用和创建分开了。
1、理解IOC/DI/DL
![](https://i-blog.csdnimg.cn/blog_migrate/856b834700b876efb25379ceba01f187.png)
-
第一步:JVM会扫描我们的jar或者war包,读取加载配置class文件,进行环境等变量的准备配置;
-
第二步:继续扫描业务字节码文件,包括相关的类,注解等class文件的全路径;
-
第三步:把第二步扫描出来的类通过反射进行实例化instance,然后注册到 IOC容器Map中;
-
第四步:完成 依赖查找注入DL 和 DI,实例化之后bean与bean之间的关系;例如加了@Resource @Autowire等注解的变量关系;
-
第五步:完成HandlerMapping的初始化,将加了@Controller和@RequestMapping的注解的url和method关系缓存到Map容器中;
-
第六步:容器启动完成,可以使用;
@Configuration //配置类
public class AutowiredPersonConfig {
@Bean
public Person person(){
return new Person();
}
}
功能代码实现的:IOC ,依赖注入和依赖查找。
@SpringBootApplication
public class SpringBootMainApp {
@Resource //DI 依赖注入
private Person person;
public static void main(String[] args) {
//IOC,所谓的控制反转,容器载入类,将Bean实例化,然后交给spring容器Map托管;
ApplicationContext app = new AnnotationConfigApplicationContext(AutowiredPersonConfig.class);
//DL 依赖查找,在容器中查找id=person的Bean实例对象;
Person person = (Person) app.getBean("person");
// TODO HERE
}
}
分析:容器启动载入类AnnotaionConfigApplicationContext完成Bean的装载和注册,@Resource里面就简单的实现了bean的依赖查找和注入。
1.1、IOC -(Inversion Of Control)
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
singletonObjects.put("person",new Person());
没有IOC之前,我们要使用对象的时候就需要自己先创建一个对象,自己控制对象的生产,获取相应的资源,另外每次产生一个对象就会往JVM内存中写入一些数据,占用了内存,也增加垃圾回收的行能消耗;
-
控制了什么?对象的new创建和生命周期,相关的依赖资源获取;
-
反转给谁?管理权反转给Spring,由Spring的 ioc容器来控制Bean生命周期;
1.2、DL-(Dependency looking )
@Resource //DI&DL 依赖查找&注入
private Person person;
实际上等价于执行了下面代码:
if (field.isAnnotationPresent(Resource.class)) {
//todo 进行属性赋值;
}
第二步:完成DL-依赖查找,从容器map中获取实例Bean Person:
Person person = singletonObjects.get("person");
1.3、DI-(Dependency injection )
field.setAccessible(true);
field.set(personInstance, person));
其实这也就是完成了person实例变量的依赖查找和注入过程。
2、Spring容器启动流程
-
第一步: refresh,容器刷新启动的时候,读取扫描jar/war包中的启动类配置文件bean.xml,载入类和application.properties文件;
-
第二步: 实例化BeanFactory这个Spring的最顶层的容器接口,创建完beanFactory,Spring就有了生产和获取getBean()的能力;另外,BeanFactory还提供一些后置处理器来保证我们的单实例非懒加载的业务bean正确创建;声明顶层map容器,初始化BeanFactory,使容器有getBean的能力;
-
第三步: finishBeanFactoryInitialization,对剩下的非懒加载单实例业务Bean进行实例化,继续扫描我们的jar或者war包,class文件,得到加了@Controller/@Component/@Service/@Repository等注解的所有要实例化的Bean的全路径名beanDefinationName;
-
第四步:通过BeanName开始从缓存也就是ioc容器map中直接获取bean实例:通过getBean()-doGetBean() ->getSingleton("beanName") —> map.getBean ("beanName"),先看IOC容器map缓存中是否有我们的singletonBean,有就 直接return,流程结束;
-
第一步:创建对象 , createBean (),拿到class类对象,通过反射得到构造函数, 创建对象,new Person();
-
第二步:属性赋值 ; populateBean():person. setName("king")
-
第三步:执行初始化方法 initializeBean ,代理对象通过applyBeanPostProcessorsBeforeInitializatio n和applyBeanPostProcessorsAfterInitialization进行增强bean的初始化前后增强 ;
-
至此,bean的创建完成,将单实例bean注册到ioc容器map中;
-
finishRefresh();Spring发送容器事件消息,我启动完成了,你可以做事情了;
3、Spring容器启动源码分析
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh(); //统一入口
}
refresh() 刷新开始:
@Override //容器刷新入口:
public void refresh() throws BeansException, IllegalStateException {
//调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//1、告诉子类启动refreshBeanFactory()方法,实例化创建BeanFactory,用来获取和创建Bean;
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//为BeanFactory配置容器特性,例如类加载器、事件处理器等
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//aop相关bean的创建
//为BeanFactory注册BeanPost事件处理器.和业务bean执行的时机不一样而已,其他都一样;
//BeanPostProcessor是Bean后置处理器的创建,用于监听容器触发的事件
registerBeanPostProcessors(beanFactory);
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//2、初始化所有剩余的非懒加载的单实例 — 业务Bean—也就是java中写的Bean文件;
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
//容器创建完成,为什么是finish,因为spring中有很多的事件监听机制,告诉监听者我启动完了,你可以做一些事情了;
finishRefresh();
}
开始创建非懒加载的单实例业务Bean:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
//实例化所有剩下的非懒加载单实例业务Bean
beanFactory.preInstantiateSingletons();
}
得到所有需要实例化的单实例Bean的全路径名,bean信息的定义 -用来生成这个bean的,然后挨个循环实例化:
@Override
public void preInstantiateSingletons() throws BeansException {
String FACTORY_BEAN_PREFIX = "&";
//得到所有的需要实例化的Bean的名字
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans…
//挨个循环获取或者创建这个beanName;
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {//获取或者创建这个bean
getBean(beanName);
}
}
}
在创建一个bean之前,先到ioc容器map中去获取相关的bean,如果该bean已经创建,则直接获取返回,不再创建,如果容器map中没有,则进行创建。这也是单例的体现,只创建一次,每次获取的对象都是同一个,可以验证打印它的地址是相同的。
@Override //获取bean信息
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
继续获取bean:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
//将bean标记为已创建
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
// Eagerly check singleton cache for manually registered singletons.
//通过bean的名字到我们的 IOC大map-其实就是一个缓存 中获取 bean;
Object sharedInstance = getSingleton(beanName);
//如果缓存中有这个bean,则直接返回;
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
//如果缓存中没有这个bean,则直接开始创建这个bean;
else {
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
从缓存容器map中获取bean单实例;
//private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//直接在map中get
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) { //同步获取;
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
//如果容器中有bean,则直接返回;
return singletonObject;
}
如果容器中有这个单实例bean则直接返回创建的流程结束;如果缓存中还没有我们需要的实例Bean,这时候就会开始创建我们的Bean实例:
-
第一步:通过反射创建对象,new Person();
-
第二步:属性赋值;person.set("king")
-
第三步:执行Bean初始化方法,对于动态代理的对象Bean进行init前后拦截增强;
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//给个机会返回一个代理对象,这里什么都没做,因为aop的bean是普通的bean的创建过程;
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
try {
//开始创建
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
创建bean,这里已经有内存地址了,也就是完成了对象的实例化:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//这里bean先创建对象,已经有内存地址;相当于Person person = new Person();
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Spring是通过反射来创建对象,通过createBeanInstance()发现具体创建对象步骤如下:
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
//反射获取构造函数
constructorToUse = clazz.getDeclaredConstructor();
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
//第一步:反射创建实例完成 等价于Person person = new Person();
return BeanUtils.instantiateClass(constructorToUse);
}
Object exposedObject = bean;
try {
//第二步:属性的赋值和初始化,等价于 person.setName("king");
populateBean(beanName, mbd, instanceWrapper);
//第三步:bean的初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
initializedBean主要是对bean完成一些初始化工作,比如在做动态代理的时候,这里就用到了,对当前的Bean初始化执行前和执行后做一些增强的处理工作,
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {//对bean的初始化
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//对bean出世化的前置处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//对bean初始化的后置处理器
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
至此,一个业务bean的实例化就完成了,结束之后,将这个bean放入到我们的IOC容器map中去,供后期业务 DI/DL使用;