设为首页 加入收藏

TOP

spring加载bean流程解析(二)
2019-10-09 19:56:03 】 浏览:215
Tags:spring 加载 bean 流程 解析
数值,我们就可以在这个方法实现中将null值转换为特定的值


3.2.3:BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName)。可以在这个方法中进行bean的实例化之后的处理,比如我们的自定义注解,对依赖对象的版本控制自动路由切换。比如有一个服务依赖了两种版本的实现,我们如何实现自动切换呢?这时候可以自定义一个路由注解,假如叫@RouteAnnotaion,然后实现BeanPostProcessor接口,在其中通过反射拿到自定义的注解@RouteAnnotaion再进行路由规则的设定。



3.2.4:SmartInitializingSingleton.afterSingletonsInstantiated


4.1:容器启动运行阶段


4.1.1:SmartLifecycle.start


容器正式渲染完毕,开始启动阶段,bean已经在spring容器的管理下,程序可以随时调用


5.1:容器停止销毁
5.1.1:SmartLifecycle.stop(Runnable callback) 


spring容器停止运行
5.1.2:DisposableBean.destroy()


spring会将所有的bean销毁,实现的bean实例被销毁的时候释放资源被调用


四:一些关键性的问题


4.1:FactoryBean和BeanFactory的区别?



BeanFactory是个bean 工厂类接口,是负责生产和管理bean的工厂,是IOC容器最底层和基础的接口,spring用它来管理和装配普通bean的IOC容器,它有多种实现,比如AnnotationConfigApplicationContext、XmlWebApplicationContext等。



FactoryBean是FactoryBean属于spring的一个bean,在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,是一个可以生产对象和装饰对象的工厂bean,由spring管理,生产的对象是由getObject()方法决定的。注意:它是泛型的,只能固定生产某一类对象,而不像BeanFactory那样可以生产多种类型的Bean。在对于某些特殊的Bean的处理中,比如Bean本身就是一个工厂,那么在其进行单独的实例化操作逻辑中,可能我们并不想走spring的那一套逻辑,此时就可以实现FactoryBean接口自己控制逻辑。


4.2:spring如何解决循环依赖问题


循环依赖问题就是A->B->A,spring在创建A的时候,发现需要依赖B,因为去创建B实例,发现B又依赖于A,又去创建A,因为形成一个闭环,无法停止下来就可能会导致cpu计算飙升


如何解决这个问题呢?spring解决这个问题主要靠巧妙的三层缓存,所谓的缓存主要是指这三个map,singletonObjects主要存放的是单例对象,属于第一级缓存;singletonFactories属于单例工厂对象,属于第三级缓存;earlySingletonObjects属于第二级缓存,如何理解early这个标识呢?它表示只是经过了实例化尚未初始化的对象。Spring首先从singletonObjects(一级缓存)中尝试获取,如果获取不到并且对象在创建中,则尝试从earlySingletonObjects(二级缓存)中获取,如果还是获取不到并且允许从singletonFactories通过getObject获取,则通过singletonFactory.getObject()(三级缓存)获取。如果获取到了则则移除对应的singletonFactory,将singletonObject放入到earlySingletonObjects,其实就是将三级缓存提升到二级缓存,这个就是缓存升级。spring在进行对象创建的时候,会依次从一级、二级、三级缓存中寻找对象,如果找到直接返回。由于是初次创建,只能从第三级缓存中找到(实例化阶段放入进去的),创建完实例,然后将缓存放到第一级缓存中。下次循环依赖的再直接从一级缓存中就可以拿到实例对象了。



五:测试


我们来写一个测试类,验证一下上面的问题:


5.1:首先声明一个自定义的Bean


 


@Component
public class CustomBean {
    public CustomBean(){
        System.out.println("调用CustomBean空的构造方法");
    }
}


 


5.2:声明一个Bean来实现BeanPostProcessor


 


package com.wyq.spring.bean;


import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;


/**
 * @Author: wyq
 * @Desc:
 * @Date: 2019/9/1 15:36
 **/
@Component
@Scope("singleton")
public class TestBean implements BeanPostProcessor, SmartInitializingSingleton, InstantiationAwareBeanPostProcessor, DisposableBean{


    private static final String BEAN_NAME= "customBean";


    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (BEAN_NAME.equals(beanName)) {
            System.out

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇深入理解动态代理源码 下一篇通过编写扫雷游戏提高你的 Bash ..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目