Я пытаюсь реализовать инъекцию зависимостей в моей программе Java SE с использованием сварки, и у меня проблемы с использованием производителя с областью применения. Это PoC моей проблемы с минимальным кодом. MyBean
класс:Как получить ApplicationScoped производителя в Java SE через сварку?
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();
}
}
}
Когда я пытаюсь запустить это, я получаю следующее исключение:
Исключение в потоке "основной" 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) по адресу 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 (Thread. java: 745) Вызвано: org.jboss.weld.exceptions.UnproxyableResolutionException: WELD-001435: Нормальный класс bean-класса MyBean не является проксибельным, поскольку он не имеет конструктор no-args - метод-производитель [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
и производитель без какой-либо области, он работает так, как я хочу, значит, у меня будет один экземпляр компонента во всем жизненном цикле моего приложения.
Но установка области впрыска как @ApplicationScoped
такая же, как и по умолчанию, т.е. новый экземпляр для каждого запроса.
В чем причина всего этого?
Добавление конструктора по умолчанию делает зависимости неоднозначными, поскольку сварной шов не знает, использовать ли производитель или непосредственно вставлять сам компонент. – Mehraban