RequestScope がアクティブであると仮定します (cdi-unit の @InRequestScope を使用)
与えられた
package at.joma.stackoverflow.cdi;
public class Product {
public Product(String withValue){
this.value = withValue;
}
public String value;
}
- そのアクティブなリクエストスコープへの製品の注入
package at.joma.stackoverflow.cdi;
import javax.inject.Inject;
import org.jglue.cdiunit.AdditionalClasses;
import org.jglue.cdiunit.CdiRunner;
import org.jglue.cdiunit.InRequestScope;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(CdiRunner.class)
@AdditionalClasses({ Producer.class, SomeCache.class })
public class ExpectedTest {
@Inject
Product productA;
@Inject
Product productB;
@Test
@InRequestScope
public void testScoping() {
Assert.assertNotNull(productA);
System.out.println(productA.value);
Assert.assertNotNull(productB);
}
}
- 依存プロデューサーを使用する (InjectionPoint パラメーターを使用するため、依存する必要があります)
package at.joma.stackoverflow.cdi;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.inject.Inject;
public class Producer {
public static final String VALUE_B = "valueB";
public static final String VALUE_A = "valueA";
@Inject
SomeCache someCache;
@Produces
public Product produceProduct(InjectionPoint ip) {
if (!VALUE_B.equals(someCache.getCacheValue())) {
someCache.setCacheValue(VALUE_A);
} else {
someCache.setCacheValue(VALUE_B);
}
return new Product(someCache.getCacheValue());
}
}
- そのプロデューサーには、リクエストスコープのBeanを注入する必要があります
package at.joma.stackoverflow.cdi;
import javax.enterprise.context.RequestScoped;
@RequestScoped
public class SomeCache {
private String cacheValue;
public String getCacheValue() {
return cacheValue;
}
public void setCacheValue(String cacheValue) {
this.cacheValue = cacheValue;
}
}
これが失敗した場合、リクエスト スコープ Bean の原因
org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped
at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:708)
at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:90)
at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:165)
at org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63)
at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:83)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:125)
at at.joma.stackoverflow.cdi.SomeCache$Proxy$_$$_WeldClientProxy.getCacheValue(Unknown Source)
at at.joma.stackoverflow.cdi.Producer.produceProduct(Producer.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:88)
at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:78)
at org.jboss.weld.injection.producer.ProducerMethodProducer.produce(ProducerMethodProducer.java:95)
at org.jboss.weld.injection.producer.AbstractMemberProducer.produce(AbstractMemberProducer.java:167)
at org.jboss.weld.bean.AbstractProducerBean.create(AbstractProducerBean.java:183)
at org.jboss.weld.context.unbound.DependentContextImpl.get(DependentContextImpl.java:69)
at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.get(ContextualInstanceStrategy.java:101)
at org.jboss.weld.bean.ContextualInstance.get(ContextualInstance.java:50)
at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:761)
at org.jboss.weld.manager.BeanManagerImpl.getInjectableReference(BeanManagerImpl.java:861)
at org.jboss.weld.injection.FieldInjectionPoint.inject(FieldInjectionPoint.java:92)
at org.jboss.weld.util.Beans.injectBoundFields(Beans.java:375)
at org.jboss.weld.util.Beans.injectFieldsAndInitializers(Beans.java:386)
at org.jboss.weld.injection.producer.ResourceInjector$1.proceed(ResourceInjector.java:70)
at org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:48)
at org.jboss.weld.injection.producer.ResourceInjector.inject(ResourceInjector.java:72)
at org.jboss.weld.injection.producer.BasicInjectionTarget.inject(BasicInjectionTarget.java:121)
at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:159)
at org.jboss.weld.context.AbstractContext.get(AbstractContext.java:96)
at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.get(ContextualInstanceStrategy.java:101)
at org.jboss.weld.bean.ContextualInstanceStrategy$ApplicationScopedContextualInstanceStrategy.get(ContextualInstanceStrategy.java:141)
at org.jboss.weld.bean.ContextualInstance.get(ContextualInstance.java:50)
at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:99)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:125)
at at.joma.stackoverflow.cdi.ExpectedTest$Proxy$_$$_WeldClientProxy.testScoping(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.jglue.cdiunit.CdiRunner$2.evaluate(CdiRunner.java:179)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
- これは CDI ごとに予想される動作ですか?
- はいの場合、プロデューサーの依存疑似スコープのためですか?
- SomeCache がリクエスト スコープではなくアプリケーション スコープである場合、これが失敗しないのはなぜですか?
SomeCache の妥当な範囲のソリューションは何ですか?
その (動作していない) リクエスト スコープの SomeCache は、プロデューサーが最初に注入される Bean を生成するために必要なデータをキャッシュします。だからできる
- どちらにも依存しない (キャッシュが役に立たなくなるため)
- また、アプリケーション スコープまたは静的であってはなりません (スコープが広すぎる)。
理想的には、Product が注入される Bean の同じスコープに自動的にある必要があります (例では、ExpectedTest です)。別のカスタム cdi スコープである可能性がありますが、そのスコープを定義するクライアント/ユーザー開発者に依存するべきではありません。意味があれば、それを「推移的なスコープ依存 Bean」と呼ぶことができます。