Spring Bean

1.Spring 中的bean的作用域有哪些?

  • Singleton: 唯一bean实例,Spring中的bean默认都是单例的。
  • prototype:每次请求都会创建一个新的bean实例。
  • request:每一次HTTP请求都会产生一个新的bean,该bean仅在HTTP request内有效。
  • session:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP session内有效。
  • global-session:全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。Portlet是能够生成语义代码(例如HTEML)片段的小型Java Web插件。他们基于portlet容器,可以像servlet一样处理HTTP请求。但是,与servlet不同,每个portlet都有不同的会话。

2.Spring中的单例bean的线程安全问题了解吗

单例bean存在线程问题,主要是因为当多个线程操作同一个对象的时候,对这个对象非静态成员变量的写操作会存在线程安全问题。

常见的解决方法:

  • 在Bean对象中尽量避免定义可变的成员变量
  • 在类中定义ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal中

3.@Component 和@Bean的区别是什么?

  1. 作用对象不同:@Component注解作用于类,而@Bean注解作用于方法。
  2. 针对一些第三类库的话,我们并不知道它的源码,也就无法直接使用注解@Component,我们可以采用@Configuration+@Bean的注解,将它注册到IOC容器中。

4.将一个类声明为Spring 的bean的注解有哪些

  1. Autowired//默认按type注入,然后按名称
  2. Qualifier(“cusInfoService”)//一般作为@Autowired()的修饰用
  3. Resource(name=“cusInfoService”)//默认按name注入,可以通过name和type属性进行选择性注入
    并且Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与spring的耦合。这样代码看起就比较优雅。

采用以下注解可实现:

  • @Component:通用的注解,可标注任意类为Spring组件。如果一个Bean不知道属于哪个层,可用使用@Component注解标注。
  • @Repository:对应持久层即DAO层,主要用于数据库相关操作。
  • @Service:对应服务层,主要涉及一些复杂的逻辑,需要用到DAO层。
  • @Controller:对应Spring MVC控制层,主要用户接受用户请求调用Service层返回数据给前端页面。

5.Spring Bean的生命周期

  1. 实例化Instantiation
  2. 属性赋值Populate
  3. 初始化Initialization
  4. 销毁Destruction

在这里插入图片描述

  1. 实例化:第一步,实例化一个bean对象
  2. 属性赋值:第二步,为bean设置相关属性和依赖
  3. 初始化:第3-7步,
    3.检查Aware的相关接口并设置相关依赖
    4.BeanPostProcessor前置处理
    3-4在初始化前进行
    5.是否实现InitializingBean接口
    6.是否配置自定义init-method
    5-6为初始化操作
    7.BeanPostProcesspor后置处理
  4. 销毁:
    8.注册Destruction相关回调接口
    第8步还未真正销毁。
    9.是否实现DisposableBean接口
    10.是否配置自定义的destory-method

Bean的实例化和BeanWrapper

容器在内部实现的时候,采用策略模式来决定以何种方式来实例化bean实例。

默认情况下,容器内部采用的是CglibSubclassingInstantiationsStrategy

容器根据bean的定义的BeanDefintion取得实例化信息,结合CglibSubclassingInstantiationStrategy以及不同的bean定义类型,就可以返回实例化完成的对象实例。

但是不是直接返回构造完成的对象实例,而是以BeanWrapper对构造完成的对象实例进行包裹,返回相应的BeanWrapper实例。

BeanWrapper接口通常在Spring框架内部使用,它有一个实现类org.springframework.BeanWrapperImpl。其作用是对某个bean进行包裹,然后对这个包裹的bean进行操作,比如设置或者获取bean的相应属性值。而在第一步结束返回BeanWrapper实例而不是原先的对象实例,就是为了第二步设置对象属性。

使用BeanWrapper对bean实例操作很方便,可以免去直接使用Java反射API操作对象实例的繁琐。

各色的Aware接口

当对象实例化完成并且相关属性以及依赖设置完成之后,Spring容器会检查当前对象实例是否实现了一系列的以Aware命名结尾的接口定义。如果是,则将这些Aware接口定义中规定的依赖注入给当前实例:

  • BeanNameAware:将对象实例的bean定义对应的beanName设置到当前对象实例。
  • BeanClassLoaderAware:将对应加载当前bean的ClassLoader注入当前对象实例。
  • BeanFactoryAware:注入当前BeanFactory容器的引用。

以上几个Aware接口只是针对BeanFactory类型的容器而言的。
对于ApplicationContext类型的容器,也存在几个Aware相关接口。使用的是下面要说的BeanPostProcessor方式。

BeanPostProcessor

BeanPostProcessor会处理容器内所有符合条件的实例化后的对象实例。

常用的场景:

  1. 对于标记接口的实现类,进行自定义处理。
  2. 为当前对象提供代理实现,生成对象的代理类,然后返回。

总结:

  • 首先是实例化、属性赋值、初始化、销毁这4个大阶段
  • 再是初始化的具体操作,有Aware接口的依赖注入、BeanPostProcessor在初始化前后的处理已经IntializingBean和init-method的初始化操作。
  • 销毁的具体操作,有注册相关销毁回调接口,最后通过DisposableBean和destory-method进行销毁。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值