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



我将对象定义为具有作用域"thread"。

在代码的某个地方,实例是用@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);
}
}

最后定义了一个Async方法[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

谢谢。

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

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

  • 用CCD_ 8对CCD_。这将使spring围绕您的对象创建一个代理,它将把所有调用委托给正确作用域的实例。

最新更新