自动装配@Scope(value =“request”,proxyMode = ScopedProxyMode.INTERFACES)对象时出错

时间:2014-01-04 18:19:02

标签: java spring spring-social

我正在尝试使用Spring Social reference doc here中描述的Spring社交通信控制器实现与服务提供商的连接。

初始化时,以下服务找不到currentUser bean。我得到了例外

 `Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.dynamease.serviceproviders.user.User com.dynamease.serviceproviders.SPResolver.currentUser; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.dynamease.serviceproviders.user.User] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

初始化以下服务时会发生这种情况:

@Service
public class SPResolver {

public SPResolver() {
}

@Autowired
private User currentUser;

@Autowired
private ConnectionRepository connectionRepository;

 public void connectUser(String id) {
 currentUser.setId(id);
     }

public void disconnectUser() {
    this.currentUser = null;
}

这是配置相关的配置文件部分

@Bean
@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
public User currentUser() {
    return new User(null);
}

@Bean
@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
public ConnectionRepository connectionRepository() {
    String id = currentUser().getId();
    if (id == null) {
        throw new IllegalStateException("Unable to get a ConnectionRepository: no user signed in");
    }
    return usersConnectionRepository().createConnectionRepository(id);
}

我怀疑使用“新用户”进行bean定义可能是原因以及为什么在spring样本中他们使用静态SecurityContext类,其中用户信息封装在threadlocal内但未在doc中找到任何令人信服的信息关于它。 在此先感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

感谢Sotirios的回答和评论交流,我仔细阅读了Spring参考文档的第5.5和9.6节,并发现了问题:

如果你确保:单身@Service(在我的情况下是SPResolver)引用会话或请求范围bean,这是可以的:

  1. 您使用某种AOP代理机制,以便在最初创建@Service并且不存在作用域bean时,会创建一个代理,然后在程序执行期间正确引用作用域bean。这就是我在初始代码中通过currentUser bean创建中的@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)行实际执行的操作。
  2. scoped bean需要在@Service通过接口引用,而不是直接引用Java类,我没有为User类做。实际上,我为ConnectionRepository Bean采用的复制粘贴示例正在起作用,因为ConnectionRepository是一个接口。
  3. 以下是工作配置类代码:

    @Bean
    @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
    public CurrentUserContext currentUser() {
        return new CurrentUserContextImpl();
    }
    
    @Bean
    @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
    public ConnectionRepository connectionRepository() {
        String id = currentUser().getId();
        if (id == null) {
            throw new IllegalStateException("Unable to get a ConnectionRepository: no user signed in");
        }
        return usersConnectionRepository().createConnectionRepository(id);
    }
    

    和@Service声明:

    @Service
    public class SPResolver {
    
    public SPResolver() {
    }
    
    @Autowired
    private CurrentUserContext currentUser;
    
    @Autowired
    private ConnectionRepository connectionRepository;
    

答案 1 :(得分:1)

您的SPResolver班级是@Service,默认的单一范围。因此,它将在启动时初始化。

您的User bean是request范围,因此可以为每个请求创建一个新实例。

但是,在启动时,没有这样的请求,因此无法注入User bean,因为它不存在。


这可能不是这里的根本原因。你似乎更有可能没有扫描正确的配置,但你最终会遇到上述问题。