Spring bean生命周期

bean实例化:创建对象,通过底层的class反射创建。
bean初始化:就是执行那个定义的初始化方法,和java对象的初始化不是一个东西。

1.spring bean的生命周期

  • 实例化前)执行postProcessBeforeInstantiation方法,这里返回的对象会替换掉原来的bean。

  • Bean容器利用java 反射机制实例化Bean,执行clinit,init(构造器)方法。

  • (实例化之后)执行postProcessAfterInstantiation方法,这里如果返回false会跳过依赖注入阶段。

  • 执行依赖注入,如@Autowire,@Value,@Resource。

  • Bean容器为实例化的Bean设置属性值;就是下面的这些接口。

  • 如果Bean实现了BeanNameAware接口,则执行setBeanName方法;

  • 如果Bean实现了BeanClassLoaderAware接口,则执行setBeanClassLoader方法;

  • 如果Bean实现了BeanFactoryAware接口,则执行setBeanFactory方法;

  • 如果Bean实现了ApplicationContextAware接口,则执行setApplicationContext方法;

    • Aware接口的主要作用是感知,比如有两个bean

       <bean id="zhangsan"  class="com.github.jettyrun.springinterface.demo.aware.beannameaware.User">
              <property name="name" value="zhangsan"></property>
              <property name="address" value="火星"></property>
          </bean>
       
          <bean id="lisi"  class="com.github.jettyrun.springinterface.demo.aware.beannameaware.User2">
              <property name="name" value="lisi"></property>
              <property name="address" value="火星"></property>
          </bean>
      

      其中user实现了BeanNameAware接口,user2没有,则user可以被注入bean id属性,就是那个zhangsan,而user2就不能获取到lisi。

  • 初始化之前)如果加载了BeanPostProcessor相关实现类,则执行postProcessBeforeInitialization方法,这里返回的对象会替换掉原来的bean

  • 如果Bean定义初始化方法(配置init-method、实现了InitializingBean接口),则执行定义的初始化方法;

  • 初始化之后)如果加载了BeanPostProcessor相关实现类,则执行postProcessAfterInitialization方法;

  • 当要销毁这个Bean时,如果自定义了销毁方法(PreDestroy注解、配置destroy-method、实现了DisposableBean接口),则执行定义的销毁方法。

@Component
public class LightMgrService {
@Autowired
private LightService lightService;
public LightMgrService() {
lightService.check();
}
}

这样写会导致空指针异常,因为@Autowired注解的注入是在构造器执行之后的,先初始化bean,再注入属性

3.spring bean的作用域

  • Singleton,这是Spring的默认作用域,也就是为每个IOC容器创建唯一的一个Bean实例。
  • Prototype,针对每个getBean请求,容器都会单独创建一个Bean实例。
  • 如果是web容器,则支持以下三种
    • Request,为每个HTTP请求创建单独的Bean实例。
    • Session,很显然Bean实例的作用域是Session范围。(另外关于session,浏览器关闭session并不会销毁,可以主动销毁或等待过期,如果sessionid放在会话cookie里,则下次访问会新返回一个sessionid,如果sessionid放在硬盘cookie里,下次访问还是这个sessionid)
    • application,应用程序域,应用程序(ServletContext)启动时创建,应用程序关闭时销毁。

4.上面那个问题还可以这样

@Component
public class LightMgrService {
@Autowired
private LightService lightService;
@PostConstruct
public void init() {
lightService.check();
    }
}

利用@PostConstruct注解,构造器和Autowired和postconstruct的执行顺序是:Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)

5.使用@ Bean 注解的方法所注册的 Bean 对象,如果用户不设置 destroyMethod 属性,此时 Spring 会检查当前 Bean 对象的原始类中是否有名为 shutdown 或者 close 的方法,如果有,此方法会被 Spring 记录下来,并在容器被销毁时自动执行;当然如若没有,那么自然什么都不会发生。而使用@component或@service则不会。

posted @ 2022-03-29 20:59  YUKINO62  阅读(37)  评论(0编辑  收藏  举报