我有一些调度程序任务每1小时触发UserInfoServiceExecutor,AdminInfoServiceExecutor服务(两个服务同时启动)。
问题是这些服务使用LoggerService和LoggerService搜索方法几乎需要5分钟才能完成(我的意思是while循环)。由于要搜索userInfo日志,您需要使用某个用户帐户登录并获取管理员日志,您需要使用某个管理员帐户登录(这意味着将返回不同的sessionTokens),
AdminInfoServiceExecutor在它启动之后是否覆盖UserInfoServiceExecutor sessionToken?
@Service
public class UserInfoServiceExecutor {
@Autowired
private LoggerService loggerService;
public void saveUserInfos(){
loggerService.loginAndSearch("userInfo");
}
}
@Service
public class AdminInfoServiceExecutor {
@Autowired
private LoggerService loggerService;
public void saveAdminInfos(){
loggerService.loginAndSearch("adminInfo");
}
}
@Service
public class LoggerService{
private String sessionToken;
public String loginAndSearch(String key){
if(key.equals("userInfo"))
sessionToken = login(user);
if(key.equals("adminInfo"))
sessionToken = login(admin);
search(key);
}
public String search(String keyword){
while(hasMoreResults){
getResults(keyword, sessionToken);
}
}
}
编辑:我正在使用默认的Spring范围。(Singleton)
答案 0 :(得分:3)
您的问题主要是关于 LoggerService bean的范围,就spring容器而言,它处理范围以及在定义bean时的声明方式,Spring&# 39; s的默认范围是Singleton。
因此,您没有提及作为范围,它将作为 Singleton 范围进行管理
由于您有sessionToken
作为班级成员,因此有可能被覆盖,您可能需要在此处理同步。
注意:同步块或同步方法仅适用于 单个JVM的权限,以防您部署代码/应用程序 不同JVM中的集群环境这种同步方法 不行。
答案 1 :(得分:1)
使用@Autoired Spring注入一个spring bean的引用。现在,如果jijected bean的范围是Singleton(默认行为),您将在每个@Autowired依赖项中获得相同的实例,并且在所有请求中,您的服务将看到相同的bean。如果你的spring bean在每个@Autowired注入中被配置为Prototype范围,那么将会注入一个新的Spring bean实例,但即使在这种情况下,在每个方法调用中,bean都是相同的。说,因为在你的情况下,你需要一个statefull bean而不是一个无状态bean pheraps将更好地使用"域对象"而不是春豆。我想说你可以使用一个用@Configurable注释的cljeical pojo,并在每个请求中创建一个新对象,并为你的propouse使用一个新对象。在可配置对象上使用@Configurable,在配置中使用@EnableAspectJAutoProxy @EnableSpringConfigured @EnableLoadTimeWeaving
我希望它可以帮到你
编辑:
我有一个自己的开源项目PhoneBoock(https://github.com/mrFlick72/phonebook/tree/master/phonebook-java-config),其中我遇到了类似的问题。我有一个PhoneBookUser的构建器,我的用户有一个带有spring安全PasswordEncoder的passowrd。一开始我有一个构建PhoneBookUser PhoneBookUserBuilder的单例bean,但是如果两个用户在单一过程中创建一个新实体,那么我很可能会成为一个单例,我有一个交错的ov交互可能会破坏数据。为了解决这个问题,我用
重构了我的代码@Configurable 公共类PhoneBookUserBuilder
使用@Configurable我可以使用new运算符创建一个新对象,并使用弹簧DI的优势注入PasswordEncoder。这种方法解决了我的问题。我可以建议考虑它可能对你有帮助。
答案 2 :(得分:0)
是的,在这种情况下,因为您将拥有一个LoggerService bean实例。通常您没有有状态服务,因此如果您不想在其他Spring bean之间共享该状态,请将sessionToken字段转换为本地变量。