Bean
bean生命周期
Bean 容器找配置文件找到bean的定义,使用反射创建bean实例有属性就调用set(),有名字就调用setName(),如果实现了 BeanClassLoaderAware 接口,调用 setBeanClassLoader()方法,传入 ClassLoader对象的实例,如果实现了其他 *.Aware接口,就调用相应的方法,如果有和加载这个 Bean 的 Spring 容器相关的BeanPostProcessor对象,执行postProcessBeforeInitialization() 方法,如果Bean实现了InitializingBean接口,执行afterPropertiesset()方法。
如果 Bean在配置文件中的定义包含init-method 属性,执行指定的方法。
如果有和加载这个Bean的 Spring容器相关的 BeanPostprocessor对象,执行postProcessAfterInitialization()方法
当要销毁Bean 的时候,如果Bean 实现了DisposableBean接口,执行destroy()方法。
当要销毁Bean的时候,如果 Bean在配置文件中的定义包含destroy-method 属性,执行指定的方法。
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是能够生成语义代码(例如:HTML)片段的小型Java Web插件。它们基于portlet容器,可以像servlet一样处理HTTP请求。但是,与 servlet 不同,每个 portlet 都有不同的会话
Spring 中的单例 bean 的线程安全问题
多个线程操作对象的确会产生安全问题,但是一般来说我们常用的 Controller、Service、Dao 这些 Bean 是无状态的。无状态的 Bean 不能保存数据,因此是线程安全的。
如果为了万无一失可以:
在类中定义一个 ThreadLocal 成员变量,将需要的可变成员变量保存在ThreadLocal 中(推荐的一种方式)。
改变 Bean 的作用域为 “prototype”:每次请求都会创建一个新的 bean 实例,自然不会存在线程安全问题。