Java 自动连接@Scope(值=“请求”,proxyMode=ScopedProxyMode.INTERFACES)对象时出错

Java 自动连接@Scope(值=“请求”,proxyMode=ScopedProxyMode.INTERFACES)对象时出错,java,spring,spring-social,Java,Spring,Spring Social,我正在尝试使用spring社交通信控制器实现与服务提供商的连接,如中所述 初始化时,以下服务找不到currentUser bean。我有个例外 `Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.dynamease.serviceproviders.user.User com.dynamease.serviceproviders.SP

我正在尝试使用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中,但在文档中没有找到任何令人信服的信息。
提前感谢您的帮助。

您的
SPResolver
类是一个具有默认单例作用域的
@Service
。因此,它将在启动时初始化

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

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



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

您的
SPResolver
类是一个具有默认单例作用域的
@Service
。因此,它将在启动时初始化

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

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



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

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

如果您确保:

  • 您应该使用某种AOP代理机制,以便在最初创建@Service时,当作用域bean不存在时,创建一个代理,然后在程序执行期间正确引用作用域bean。这就是我在最初代码中通过currentUser bean创建中的
    @Scope(value=“request”,proxyMode=ScopedProxyMode.INTERFACES)
    行实际所做的
  • 作用域bean需要通过接口在
    @Service
    中引用,而不是直接与Java类引用,这不是我为
    用户
    类所做的。实际上,我为ConnectionRepository Bean提供的复制粘贴示例是作为ConnectionRepository是一个接口工作的
  • 以下是工作配置类代码:

    @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
    public class SPResolver {
    
    public SPResolver() {
    }
    
    @Autowired
    private CurrentUserContext currentUser;
    
    @Autowired
    private ConnectionRepository connectionRepository;
    

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

    如果您确保:

  • 您应该使用某种AOP代理机制,以便在最初创建@Service时,当作用域bean不存在时,创建一个代理,然后在程序执行期间正确引用作用域bean。这就是我在最初代码中通过currentUser bean创建中的
    @Scope(value=“request”,proxyMode=ScopedProxyMode.INTERFACES)
    行实际所做的
  • 作用域bean需要通过接口在
    @Service
    中引用,而不是直接与Java类引用,这不是我为
    用户
    类所做的。实际上,我为ConnectionRepository Bean提供的复制粘贴示例是作为ConnectionRepository是一个接口工作的
  • 以下是工作配置类代码:

    @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
    public class SPResolver {
    
    public SPResolver() {
    }
    
    @Autowired
    private CurrentUserContext currentUser;
    
    @Autowired
    private ConnectionRepository connectionRepository;
    

    我认为范围注释的代理部分实际上是用来处理这个问题的…@Yves你认为它应该代理什么?还没有请求。@Yves请通读。我以为作用域批注的代理部分实际上是用来处理这个问题的…@Yves你认为它应该代理什么?还没有请求。@Yves请通读。可以使用
    ScopedProxyMode来代替接口。TARGET\u CLASS
    可以使用
    ScopedProxyMode.TARGET\u CLASS