首页 > 其他分享 >spring中Bean生命周期

spring中Bean生命周期

时间:2023-01-05 16:22:05浏览次数:40  
标签:生命周期 Bservice 对象 spring Aservice bean Bean 缓存 创建

1. 普通java对象创建过程

举例:BusinessService businessService=new BusinessService();

编译:将.java文件编译成class文件

加载:等到类需要被初始化时(比如new) class文件被虚拟机通过类加载器加载到jvm(类加载过程参考https://www.cnblogs.com/enhance/p/10986340.html)

初始化:初始化阶段为类变量赋值为代码期望的值,供我们使用

简单来说,普通java环境创建对象是用Class对象作为模板进来创造出具体的实例

 

2. Spring管理Bean实例化过程

2.1 Spring bean 元信息(beanDefinition)读取阶段。

Spring启动时,spring按照声明bean方式(比如xml生命bean,又比如使用@Configuration @Bean @Service等注解声明bean等)去读取声明的信息

2.2 spring bean 注册阶段

这些信息被封装成BeanDefination,最后把这些信息收集到beanDefinationMap中。至此spring声明的bean已经注册到ioc容器

 ——>遍历beanDefinationMap,执行BeanFactoryPostProcessor这个bean工厂后置处理逻辑,可以对bean元数据(@Scope @Lazy @DependsOn等)进行修改(比如@DependsOn会优先实例化其修饰的方法)

2.3 spring bean实例化阶段

实例化对象(只是把对象创建出来,但对象属性还没有注入,比如UserService依赖SendService,在这一步UserSerice中以来的SendService还是null)

——>把对象属性注入(比如@Autowired注解的生效就是这个阶段)

2.4 注入Aware接口

属性注入到对应bean后,判断该bean是否实现了Aware相关接口(比如

@Service
public class DemoService implements BeanNameAware, BeanClassLoaderAware {

    private String beanName;
    private String classLoader;

    @Override
    public void setBeanName(String name) {
        beanName = name;
    }

    public String getBeanName() {
        return beanName;
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader.toString();
    }

    public String getClassLoader() {
        return classLoader;
    }
}
View Code

 

   Aware类型接口的作用就是让我们能拿到spring容器中的一些资源,Aware之前的名字就是可以拿到的资源,比如BeanNameAware可以拿到BeanName)

2.5 BeanPostProcessor

上边步骤bean对象已经被正确构造,但如果想要对象被使用前再进行一些自定义的处理,就可以通过beanpostprocessor接口实现。

BeanPostProcessor接口提供两个函数:postProcessBeforeInitialzation:这个函数先于InitialzationBean执行,称为前置处理

                postProcessAfterInitialzation:这个函数在InitialzationBean之后执行,称为后置处理

——>before方法执行完,则执行init相关方法比如@PostConstruct、实现了InitializingBean接口、init-method方法

——>执行BeanpostProcessor的after方法

——>基本流程走完后,可以获取到对象去使用

2.6 DisposableBean和destroy-method

好init-method一样,通过给destroy-method指定函数就可以在bean销毁前执行指定的逻辑

 

3.三级缓存解决循环依赖问题

 

a)假设先创建Aservice的bean。在bean实例化阶段,先创建出Aservice的bean,创建出Asercvice的对象后就创建Aservice对应的ObjectFactory放到三级缓存。

b) 然后Aservice继续往下走,到了注入属性Bsercice阶段,开始处理@Autowired要注入Bservice对象,此时会从一级缓存到三级缓存开始依次查找有没有Bservice对应的bean,此时肯定是没有Bservice的。

c)  此时Aservice的注入Bservice过程暂停,现在去创建Bservice,只有Bservice创建完后才能注入给Aservice

d) 于是Bservice开始创建,先实例化一个Bservice对象然后缓存到对应的一个ObjectFactory到第三季缓存,然后就到需要处理@Autowird注解注入Aservice时候,此时先去一级缓存找Aservice没有,再去二级缓存也没有Aservice,直到三级缓存找到Aservice,这样就拿到早起的Aservice对象。然后将早期的AService对象放到二级缓存,为什么需要放到二级缓存,主要是怕还有其他的循环依赖,如果还有的话,直接从二级缓存中就能拿到早期的AService对象。

e) 虽然Bservice注入的是早期的Aservice对象(仅仅是因为早期的Aservice对象可能有些bean创建的步骤没有完成),但跟最后完全创建好的Aservice bean是同一个对象

f) 此时Bservice中@Autowired Aservice步骤完成,经过其他springbean创建步骤后Bservice完全创建完成

g) Bservice创建完成后,将Bservice放到一级缓存,然后清空二三级缓存

h) 此时Aservice继续之前暂停@Autowired Bservice步骤。

i) 这样Bservice创建过程中注入早起三级缓存中Aservice,然后在Aservice注入一级缓存中Bservice。就这样解决循环依赖问题


参考文献

https://www.zhihu.com/question/38597960

https://jishuin.proginn.com/p/763bfbd750e7

https://www.zhihu.com/question/38597960/answer/2336854085

https://zhuanlan.zhihu.com/p/518361118

标签:生命周期,Bservice,对象,spring,Aservice,bean,Bean,缓存,创建
From: https://www.cnblogs.com/enhance/p/17024932.html

相关文章

  • 【SpringBoot】创建项目与启动
     创建项目说明  查看JDK配置    ......
  • Spring bean注入问题:NoUniqueBeanDefinitionException解决方案归纳
    引言   spring实现的bean自动注入在项目开发中是一个经常使用到的功能,但自动装配两个或多个bean时,会抛出NoUniqueBeanDefinitionException:Noqualifyingbeanoftyp......
  • 提示错误:Could not autowire. No beans of ‘Person‘ type found.
     SpringBoot的启动类要放到根目录下,刚开始建项目的时候,IDEA自动把启动类放到了main/java/com.xxx.项目名这个包下如图: ......
  • RESTful风格与Spring注解
    RESTfulL是一种网络应用程序的设计风格和开发方式,即接口请求方式和路径的一种风格。普通风格:localhost:8080/add?a=1&b=2RestFul风格:localhost:8080/add/1/2GET获......
  • Spring MVC
    1、​​SpringMVC—@RequestMapping原理讲解-1​​2、​​SpringMVC—@RequestMapping原理讲解-2​​3、​​SpringMVC判定返回view的依据​​4、​​SpringMVC源......
  • Spring源码分析
    一、Java注解​​全面解析JAVA注解​​​​JAVA注解的基本原理​​​​秒懂,Java注解(Annotation)你可以这样学​​​​Java编译时注解处理器(APT)详解​​二、Java反射​​Ja......
  • SpringBoot之HandlerInterceptor拦截器的使用
    ​​1、SpringBoot之HandlerInterceptor拦截器的使用——(一)​​​​2、SpringBoot之HandlerInterceptor拦截器的使用——(二)自定义注解​​​​3、SpringBoot之HandlerInte......
  • Vue的生命周期
    1.beforeCreate:无法通过vm,访问data,和methods。2.created:可以通vm,访问data和methods的方法。3.beforeMount:(1).生成未经vue编译的DOM结构,        ......
  • springboot项目启动报错Command line is too long. Shorten the command line via JAR
      报错原因:springboot项目启动命令过长 方案一:修改配置点击项目启动配置项-->Enviroment-->Shortencommandline选项-->选择classpathfile或JARmanifes......
  • Spring Authorization Server(授权服务器)授权处理流程
    参考链接:https://www.zhihu.com/question/50954473/answer/2496466075https://blog.51cto.com/u_1472521/4995770关键流程摘录第一篇中关键部分如下:详细流程为:①......