Java 如何使用spring在运行时创建请求范围的bean

Java 如何使用spring在运行时创建请求范围的bean,java,spring,Java,Spring,我有一个spring应用程序,希望在运行时为每个请求创建一个bean,将其注入到另一个类中,就像CDI的@Producer一样 我的bean只是一个简单的POJO: public class UserDetails { private String name; // getter / setter ... public UserDetails(String name) { this.name = name; } } 我的制作人课是这样的:

我有一个spring应用程序,希望在运行时为每个请求创建一个bean,将其注入到另一个类中,就像CDI的
@Producer
一样

我的bean只是一个简单的POJO:

public class UserDetails {

    private String name;

    // getter / setter ... 

    public UserDetails(String name) {
        this.name = name;
    }
}
我的制作人课是这样的:

@Configuration
public class UserFactory {

    @Bean
    @Scope("request")
    public UserDetails createUserDetails() {
        // this method should be called on every request
        String name = SecurityContextHolder.getContext()
                        .getAuthentication().getPrincipal(); // get some user details, just an example (I am aware of Principal)

        // construct a complex user details object here
        return new UserDetails(name)
    }
}
这是应该注入
UserDetails
实例的类:

@RestController
@RequestMapping(value = "/api/something")
public class MyResource {

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public List<String> getSomething(UserDetails userDetails) {
        // the userdetails should be injected here per request, some annotations missing?

        // do something
    }
}
@RestController
@请求映射(value=“/api/something”)
公共类MyResource{
@RequestMapping(method=RequestMethod.GET)
@应答器
公共列表getSomething(UserDetails UserDetails){
//每个请求都应该在这里注入userdetails,是否缺少一些注释?
//做点什么
}
}
问题是Spring在运行时抱怨没有默认构造函数(当然)

实例化[UserDetails]失败:未找到默认构造函数

但这是有意的,我想调用我自己的工厂,让它处理实例化


我怎样才能做到这一点?为什么从未调用过
UserFactory

UserDetails
中需要一个无参数构造函数

public class UserDetails {

    private String name;

    // getter / setter ... 
    public UserDetails() {
    }

    public UserDetails(String name) {
        this.name = name;
    }
}

您正试图在单例bean上注入请求范围的bean。 您需要为
UserDetails

@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES) 

基本上,您没有使用作用域代理。不能将作用域代理注入方法,必须将其注入控制器

public List<String> getSomething(UserDetails userDetails) { ... }
其思想是,
UserDetails
是一个作用域代理,当使用它时,它要么使用已经存在的对象,要么基于
@Bean
方法创建一个新的对象

此外,
UserFactory
中的
@Scope
注释必须进行如下修改才能正常工作:

@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS) 

您使用的是哪个Spring版本?我使用的是版本
4.2.5。发布版
您没有注入作用域bean。。。您只是在创建一个新实例,或者spring为您这样做。如果你想要一个作用域代理,你需要
@Autowire
把它放到你的控制器中。这是我首先想到的,但是如果我添加一个无参数构造函数,注入的bean总是
null
。这意味着仍然没有调用
UserFactory
。不,仍然是相同的异常。嗯……尝试设置
ScopedProxyMode.TARGET\u CLASS
,因为您没有使用
UserDetails
的接口。该接口与@m的答案结合使用-deinum@M.Deinum的答案更完整;)从4.3开始,您可以使用annotation@RequestScope,其中包括代理
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)