美文网首页
spring bean的作用域配置及相关问题

spring bean的作用域配置及相关问题

作者: 私奔_1f4f | 来源:发表于2018-01-29 10:45 被阅读0次

    一、spring的作用域分五种:

    1.singleton: bean的默认作用域,spring容器内存在一个实例。(用这个作用域有一个缺点待补)。

    2.prototype:一次调用,产生一次实例。原话是every be requested。

    3.reuqest:针对于http,一次请求一个实例。

    3.session:针对于http,同一个session一个实例。原话是 each HTTP session by the web container.

    4.globalSession:原话 beans for Portlet applications.单点登录。理解上,跨域session同一实例。

    二、当前遇到的需求,一个方法,入参和返回值格式比较固定,但是内容涉及计算等,相对复杂,所以要做成模版式。每次调用这个方法都返回一个新的实例,想过用ThreadLocal,模拟spring jdbcTemplate,但是存在一个问题,一个方法,如果内部不单独起线程,那么就是一个线程,我可能会在方法内部调用n(n>=1)次方法,所以ThreadLocal不可取。利用spring bean's prototype scope 可以达到我想要的目的(每次调用都会产生一个实例)。

    三、模拟模版类,将模版类简化为,里面有一个共享变量(非 volatile),一个方法,然后将当前对象注入spring容器中。如下:

    bean的生成周期大家都知道,我没有给init-method 而直接做一个无参构造函数代替。

    我要做的实验就是,在另一个类中注入此bean,然后连续调用say方法,看bean是否实例化指定次数,共享变量是否依次增加。

    如上图,是测试类,当前项目基于springboot。测试结果如下

    并没有得到我们想要的结果。实例化两次依据日志个人分析:第一次注解@Service将当前类注入到bean中,当然如果你指定lazy的话应该不会加载。第二次,@Autowired 注入。因为我在方法内部第一行打的断点。有好友说,是@Autowired的问题,应该每调一次方法 就@Autowired一次,我试过了不行,原理应该是,当前bean已经交给spring管理,所以,多少次注入结果都是一样的。

    找原因:个人直觉,定位到@Scope注解,源码如下:

    属性中value和scopeName是一样的,由@AliasFor得知。ConfigurableBeanFactory.SCOPE_PROTOTYPE="prototype"所以我上面没写错。那看最后一个属性proxyMode,指定代理类型。还有

    红色区域内,不会产生代理除非定义的类型不同与default。

    看看ScopedProxyMode里都有什么?如下:

    原来default=no,而interfaces为接口代理,也就是jdk代理,target_class为类代理。

    恍然大明白,修改自己的代码如下:

    运行:

    结果:perfect!

    分享一个坑,也有解决问题的思路。

    如果哪里有误,或者有其他建议,不用保留!!!

    相关文章

      网友评论

          本文标题:spring bean的作用域配置及相关问题

          本文链接:https://www.haomeiwen.com/subject/ezfxzxtx.html