2016-02-08 40 views
0

我想在我的Java SE程序中使用焊接實現依賴注入,並且使用應用程序作用域生產者時遇到問題。這是使用最少代碼的問題的PoC。該MyBean類:如何通過焊接在Java SE中獲得ApplicationScoped生產者?

public class MyBean implements Serializable{ 
    private int value; 

    public MyBean(int value) { 
    this.value = value; 
    } 

    public int getValue() { 
    return value; 
    } 

    public void setValue(int value) { 
    this.value = value; 
    } 
} 

注入點:

@Path("api") 
public class MyResource implements Serializable { 
    @Inject 
    private MyBean bean; 

    @GET 
    @Path("bean") 
    @Produces(MediaType.APPLICATION_JSON) 
    public Response getBean() { 
    return Response.ok(bean).build(); 
    } 
} 

,我想它的生產實例是@ApplicationScoped,生產商是:

public class BeanProducer { 

    @Produces 
    @ApplicationScoped 
    public MyBean beanProducer(){ 
    System.out.println("producing"); 
    return new MyBean(42); 
    } 
} 

而這一切都在主類綁定在一起:

public class Main { 
    public void main(@Observes ContainerInitialized event) { 
    try { 
     URI baseUri = UriBuilder.fromUri("http://localhost").port(1234).build(); 
     ResourceConfig config = new ResourceConfig(MyResource.class) 
      .register(JacksonFeature.class); 
     SimpleServer server = SimpleContainerFactory.create(baseUri, config); 
     System.in.read(); 
     server.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    } 
} 

當我嘗試運行它,我得到以下異常:

異常線程 「main」 org.jboss.weld.exceptions.DeploymentException:WELD-001410:本 注射點[BackedAnnotatedField] @Inject @ApplicationScoped 私人MyResource.bean具有非proxyable依賴性在 org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:392) 在 org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java :293) at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134) 在 org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:167) 在 org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:530) 在 org.jboss.weld .bootstrap.ConcurrentValidator $ 1.doWork(ConcurrentValidator.java:68) 在 org.jboss.weld.bootstrap.ConcurrentValidator $ 1.doWork(ConcurrentValidator.java:66) 在 org.jboss.weld.executor.IterativeWorkerTaskFactory $ 1中。調用(IterativeWorkerTaskFactory.java:60) 在 org.jboss.weld.executor.IterativeWorkerTaskFactory $ 1.call(IterativeWorkerTaskFactory.java:53) 在java.util.concurrent.FutureTask.run(FutureTask.java:266)在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:617) 在java.lang.Thread.run(線程。 org.jboss.weld.exceptions.UnproxyableResolutionException:WELD-001435: 正常範圍的bean類MyBean不可代理,因爲它沒有 無參數構造函數 - 具有限定符的生產者方法[MyBean] [@任何 @Default]聲明爲[[BackedAnnotatedMethod] @Produces @ApplicationScoped public BeanProducer.beanProducer()]。在 org.jboss.weld.util.Proxies.getUnproxyableClassException(Proxies.java:214) 在 org.jboss.weld.util.Proxies.getUnproxyableTypeException(Proxies.java:178) 在 org.jboss.weld。 bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:390) ...... 12多個

如果我定義了生產範圍,它不會工作。 如果我將注入點作用域設置爲@ApplicationScoped,而生產者沒有任何作用域,它將按我的意願工作,這意味着我將在應用程序的整個生命週期中擁有一個bean實例。

但設定噴射點作爲@ApplicationScoped的範圍是一樣的默認範圍,即每個請求的新實例。

什麼是背後的原因呢?

回答

1

這是因爲@ApplicationScoped是一個正常的範圍,它需要proxyable。爲了可代理,您需要一個無參數構造函數。

澄清你點

it works as I want, means I will have a single instance of the bean in the entire lifecycle of my app. 

這是不準確的一個。注射點不定義範圍,生產者確實。 Java中沒有類型安全的方法,因爲你可以有一個生產者字段。

+0

添加一個默認的構造使得依賴關係曖昧,因爲焊接不知道是否使用生產者或直接注入bean本身。 – Mehraban