java - Spring注入(inject)、全局变量

标签 java spring dependency-injection autowired

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

这是我的类(class)和 Spring 的注入(inject):

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 中的私有(private)字段,并且在两次执行之一中这些值可能不会正确?我错了吗?

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

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

最佳答案

What if I'll have two concurrent calls to a.doSomething(..)? The second call will overwrite the private fields in B and probably the values will not be corret in one of the two executions? Am I wrong?

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

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

重要的是要知道,如果将原型(prototype) bean 注入(inject)到单例 bean 中,那么 IoC 容器将仅创建原型(prototype) bean 的单个实例,从而使其实际上是单例。为了避免这种行为,您可以要求 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);
    } 
}

更多信息:

关于java - Spring注入(inject)、全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48550067/

相关文章:

spring bean 上下文配置

Symfony2 DI服务容器优先级/流

java - 如何在 System.exit(0) 之前打印一行到终端?同步问题

java - 如何用循环计算指数?

javascript - 从其他 JSP 中创建的 JS 函数接收 JSP 中的值

Java SE + Spring Data + Hibernate

java - 如何实现多线程以调用多个数据的 REST URL

java - JavaFX应用程序中的应用程序启动方法出现异常

.net - 将 .NET Core 登录到文件和控制台 - 带有时间戳

java - 如何访问aspectj中的私有(private)变量