gpt4 book ai didi

java - 使用 ThreadLocalTargetSource 填充的 Autowiring 对象不会为每个类填充

转载 作者:行者123 更新时间:2023-12-01 17:44:31 28 4
gpt4 key购买 nike

我的 Spring Boot 应用程序实现了 TenantStore将数据存储在 ThreadLocalTargetSource 中的示例详细信息参见this link

@Bean(destroyMethod = "destroy")
public ThreadLocalTargetSource threadLocalTenantStore() {
ThreadLocalTargetSource result = new ThreadLocalTargetSource();
result.setTargetBeanName("tenantStore");
return result;
}

工作示例允许 TenantStore由 Spring 框架设置和注入(inject)的对象。我的版本TenantFilter该文章中描述的类设置 TenantStore 的属性每当发出 Servlet 请求时对象

@Autowired
private TenantStore tenantStore;

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

if (authentication != null) {
String token = (String) request.getAttribute(ACCESS_TOKEN_VALUE);

if (token != null) {
OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token);

if (oAuth2AccessToken.getAdditionalInformation() != null) {
String tenantName = (String) oAuth2AccessToken.getAdditionalInformation().get("tenant");
storeTenantInThread(tenantName);
}
}
}

chain.doFilter(request, response);

} catch (ResourceNotFoundException e) {
log.error(e.getMessage());
} finally {
clearTenant();
}
}

private void storeTenantInThread(String tenantName) {
tenantStore.setName(tenantName);
}

private void clearTenant() {
tenantStore.clear();
}

然后我有许多服务,其中 TenantStore是 Autowiring 的,并且在每个服务中 TenantStore包含 doFilter() 中填充的信息方法。除了一节课。由于某种原因 TenantStore 的属性在这个类中仍然为空。受影响的类的名称是 MyCacheService架构如下:

@RestController
@RequestMapping("/here")
public class MyController {

@Autowired
private MyService myService

@GetMapping
public ResponseEntity myGetMethod(@RequestParam("text") String text) {
myService.myMethod(text);
return new ResponseEntity(Http.OK);
}

}

@Service
public class MyService {

@Autowired
private TenantStore tenantStore;

@Autowired
private MyOtherService myOtherService;

public void myMethod(String text) {
System.out.println(tenantStore.getName()); //works - prints name
myOtherService.myOtherMethod(text);
}

}

@Service
public class MyOtherService {

@Autowired
private TenantStore tenantStore;

@Autowired
private Map<String, MyComponent> myComponents;

public void myOtherMethod(String text) {
System.out.println(tenantStore.getName()); //works - prints name
MyComponent useThisComponent = myComponents.get("componentName");
useThisComponent.myComponentMethod(text);
}

}

@Component("componentName")
public class MyComponent {

@Autowired
private TenantStore tenantStore;

@Autowired
private MyCacheService myCacheService;

public void myComponentMethod(String text) {
System.out.println(tenantStore.getName()); //works - prints name
entityAliasCacheService.myCacheMethod(String text);
}

}

@Service
public class MyCacheService {

@Autowired
private TenantStore tenantStore;

public void myCacheMethod(String text) {
System.out.println(tenantStore.getName()); //DOES NOT WORK - tenantStore object is not null but the name property is
}
}

据我猜测,由于某种原因 TenantStoreMyCacheService正在不同的线程中填充,尽管我不知道为什么。

最佳答案

我注意到类似的行为。我通过添加 bean 依赖项解决了该问题

@Service
@DependsOn("proxiedThreadLocalTargetSource") // asks Spring to first load proxy bean
public class MyCacheService {

其中 proxiedThreadLocalTargetSource bean 的定义类似于 OP 的示例 -

  @Primary
@Bean(name = "proxiedThreadLocalTargetSource")
public ProxyFactoryBean proxiedThreadLocalTargetSource(ThreadLocalTargetSource threadLocalTargetSource) {
ProxyFactoryBean result = new ProxyFactoryBean();
result.setTargetSource(threadLocalTargetSource);
return result;
}

因此,通过添加依赖项,Spring 知道它应该在 proxiedThreadLocalTargetSource 之后加载 MyCacheService bean。如果没有这种依赖性,我注意到注入(inject)的是 TenantStore 而不是代理 bean。

关于java - 使用 ThreadLocalTargetSource 填充的 Autowiring 对象不会为每个类填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60884958/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com