繁体   English   中英

弹簧注入,全局变量

[英]Spring injection, global variables

我的问题可能是错误的,我不能这样做,但是找不到很好的解释。

这是我的课程和对Spring的投入:

public class A
{
    @Autowired
    protected B b;

    public void doSomething(Integer i)
    {
        b.doOtherStuff(i);
    }
}

这是我的B课:

public class B
{
    private Integer field;
    private List<SomeOtherClass> list = new ArrayList<>();

    @Autowired
    protected C c;

    public void doOtherStuff(Integer in)
    {
        field = in;
        list = c.getMyList(i);
    }
}

如果我要同时对a.doSomething(..)进行两次调用怎么办? 第二次调用将覆盖B中的私有字段,并且可能不会在两个执行之一中将值正确化? 我错了吗?

如果有人调用a.doSomething()并终止,后来在另一个类中使用B(通过注入)怎么办? 最后一个类是否可以预先初始化B的实例?

如果我的问题不清楚,请告诉我,我的Java和英语也不太好:D

如果我要同时对a.doSomething(..)进行两次调用怎么办? 第二次调用将覆盖B中的私有字段,并且可能不会在两个执行之一中将值正确化? 我错了吗?

list属性将被分配两次。 如果B#doOtherStuff不仅仅是分配list的值,那么您很可能会收到ConcurrentModificationException或意外的结果。

在这种情况下,当Bean需要维护依赖于执行的可变状态时,则Bean不应处于Singleton范围内。 最好的选择是将bean声明为prototype ,它由Spring IoC容器每次创建。

重要的是要知道,如果将原型Bean注入到一个Singleton Bean中,那么IoC容器将仅创建该原型Bean的单个实例,从而使其实际上成为Singleton。 为了避免这种行为,您可以要求ApplicationContext在每次方法执行时检索一个新实例:

@Component
public class A {
    @Autowired
    private ApplicationContext ctx;

    public void doSomething(Integer i) {
        //ApplicationContext will create the bean using the IoC container
        B b = ctx.getBean(B.class);
        b.doOtherStuff(i);
    } 
}

更多信息:

您认为私有变量是bean中的问题是正确的。 您可能需要阅读有关bean作用域的内容 缺省的bean作用域是singleton,这意味着对于所有调用而言,只有一个实例可以使用。

这也意味着您的私有变量将通过对Bean的所有调用来共享。 因此,在类B中,每次调用方法doOtherStuff都会覆盖变量field

通常,除非更改范围,否则在Spring bean中拥有私有变量是很糟糕的。 对此有一些例外,例如某些缓存或任何其他共享的和线程安全的逻辑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM