2014-02-08 61 views
3

我想在Spring中有一个范围变量。在Guice中它很简单:春季会话或请求范围变量

@Singleton 
class MyBean 
{ 
    @Inject @Named("session-scoped") 
    private Provider<Integer> someString; 
    void doSomething() 
    { 
     // returns a random number for a current session. 
     // Each user session should generate new number, 
     // but one session should keep the same number. 
     Integer n1 = someString.get(); 
     Integer n2 = someString.get(); 
     assert n1 == n2; 
    } 
} 
... 
class MyModule extends AbstractModule 
{ 
    @Override 
    protected void configure() 
    { 
    ... 
    } 

    @Provides 
    @SessionScoped 
    @Named("session-scoped") Integer someString() 
    { 
     return new Random().nextInt(); 
    } 
} 

我怎么能在Spring中做类似的事情?

请记住,它是java.lang.Integer,而不是某个用户bean,它不能被aop代理。

回答

0

在你的情况下,你不需要会话范围。你只需要一个单独定制的提供者实例

interface CustomProvider<E> { 
    public E get(); 
} 

@Configuration 
class TestConfig { 
    @Bean 
    public CustomProvider<Integer> factory() { 
     return new CustomProvider<Integer>() { 
      @Override 
      public Integer get() throws BeansException { 
       return new Random().nextInt(); 
      } 
     }; 
    } 
} 

,并注入其

@Inject 
private CustomProvider<Integer> factory; 

我错过了你想要的会话相同的值。 See Emerson's answer for that.


一般用于会话范围豆:

@Configuration类,可以提供具有会话范围@Bean方法。

@Bean 
@Scope(value = WebApplicationContext.SCOPE_SESSION /* or simply "session" */) 
public SomeBean someBean() { 
    return new SomeBean(); 
} 

您可以使用@Scope注释上@Component注释类为好。

在XML

<bean id="someBean" class="com.example.SomeBean" scope="session" /> 
+0

以及如何使用它?你能显示注射点吗?请记住,它是'java.lang.String',而不是SomeBean,它不能被代理。 – kan

+0

@ kan啊我没有看到。让我回到你身边。 –

+0

@ kan我认为这是你能做的最好的。匹配你在Guice做的事情。 –

0
@Component 
@Scope("session") 
public class IntegerProvider implements Provider<Integer> { 

    private Integer value = new Random().nextInt(); 

    public Integer get() { 
     return this.value; 
    } 
} 

...

@Autowired 
private Provider<Integer> integerProvider; 

...

assert this.integerProvider.get().equals(this.integerProvider.get(); 
+0

这是我已经做过的最好的自己,但我被迫在一个Provider中缓存值...在更复杂的情况下 - 值是从其他注入的bean计算的我无法在构造函数中进行初始化,它看起来更糟,我需要添加多线程安全性。 – kan

+0

这听起来像你的域模型不够强大。问问自己“这些价值是什么意思?” “他们为什么会议的范围?” “他们有什么关系?”等等。如果你可以将它们建模为一个实体对象(http://martinfowler.com/bliki/EvansClassification.html),那么你可以让该对象成为一个带有会话范围的bean,在需要的地方注入它,并让其他bean发生变异它。 –

+0

我不喜欢那个Spring是如此的侵入性,它决定了我应该如何设计领域模型。目前它只是一个缓存参数,如果它更加清楚它应该如何在域模型中,我会重构它,但由于春天我应该过度复杂我的设计,所以guice更好,它足够灵活以至于不能用样板代码和自己的胆量污染我的课程。 – kan