有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在Spring Boot中使用SimpleThreadScope,我在同一个线程中获得了一个对象的两个实例

我用范围“线程”定义对象

在代码的某些地方,实例是通过@Autowired获得的,而在另一个地方是通过context getBean()获得的,在比较对象时,它们是不同的

由于对象的作用域是“线程”,所以我希望返回相同的对象实例

下面是代码,首先我定义了一个自定义范围

@Configuration
public class ThreadScopeRegisteringBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory (ConfigurableListableBeanFactory beanFactory) throws BeansException {
        beanFactory.registerScope("thread", new SimpleThreadScope());
    }
}

测试对象定义为:

@Component
@Scope("thread")
public class ThreadScopeObject implements InitializingBean {
    private static final Logger LOGGER = LoggerFactory.getLogger(ThreadScopeObject.class);

    private String field1;

    public String getField1() {
        return field1;
    }

    public void setField1(String field1) {
        this.field1 = field1;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        LOGGER.info("****************** new object - " + this);
    }
}

服务也被定义为:

@Service
public class ThreadScopeService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ThreadScopeService.class);

    @Autowired
    private ThreadScopeObject threadScopeObject;

    public void showObject() {
        LOGGER.info ("ShowObject: " + threadScopeObject);
    }
}

最后定义了一个异步方法[RunnableService.java]:

@Async
public CompletableFuture<Map> objectInstanceTest() {
    ThreadScopeObject o = ApplicationContextHolder.getContext().getBean(ThreadScopeObject.class);

    LOGGER.info ("Thread object: " + o);

    service.showObject();

    return CompletableFuture.completedFuture(new HashMap<>());
}

运行应用程序时,我会得到以下日志:

19:15:27.094 [mcd-async-1] INFO com.mono.threadSample.ThreadScopeObject - ****************** new object - com.mono.threadSample.ThreadScopeObject@69c8f2bb
19:15:27.094 [mcd-async-1] INFO com.mono.threadSample.RunnableService - Thread object: com.mono.threadSample.ThreadScopeObject@69c8f2bb
19:15:27.094 [mcd-async-1] INFO com.mono.threadSample.ThreadScopeService - ShowObject: com.mono.threadSample.ThreadScopeObject@fd0e5b6

我想知道一个对象“线程”作用域在同一个线程中被实例化两次的原因

代码:https://github.com/saavedrah/spring-threadSample

谢谢


共 (1) 个答案

  1. # 1 楼答案

    默认情况下,ThreadScopeService是一个单例,因此当它由spring构造时,它将从创建它的线程中获得一个ThreadScopeObject,之后不会更新它。有两种方法可以解决这个问题:

    • Provider<ThreadScopeObject>ObjectFactory<ThreadScopeObject>注入ThreadScopeService并在需要时调用它们的get方法来检索作用域对象

    • @Scope("thread", proxyMode = ScopedProxyMode.TARGET_CLASS)注释ThreadScopeObject。这将使spring围绕对象创建一个代理,它将所有调用委托给范围正确的实例