Spring是否为自动装配的字段创建了一个新对象?

时间:2016-11-02 08:40:08

标签: java spring

我有一些调度程序任务每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)

3 个答案:

答案 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字段转换为本地变量。