如何在quarkus中通过ArC获得带有自定义注释的bean



我想在运行时根据用户输入找到bean,所以使用io.quarkus.arc.

然而,我不知道如何以合理的方式获得带有自定义注释的bean。只有通过实现注释接口才能工作,比如:

InstanceHandle<Service> instanceHandleA = Arc.container()
.instance(Service.class, new SupportsJobTypeImpl(JobType.A));
InstanceHandle<Service> instanceHandleB = Arc.container()
.instance(Service.class, new SupportsJobTypeImpl(JobType.B));

class SupportsJobTypeImpl implements SupportsJobType {
JobType requestedJobType;
public SupportsJobTypeImpl(JobType requestedJobType) {
this.requestedJobType = requestedJobType;
}
@Override
public JobType value() {
return requestedJobType;
}
@Override
public Class<? extends Annotation> annotationType() {
return SupportsJobType.class;
}
}

有没有一种方法可以用SupportsJobTypeImpl这样不那么繁琐的详细代码来获得instanceHandleA、instanceHandleB?

关于我的测试代码的背景信息:


public enum JobType {
A,B
}

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface SupportsJobType {
JobType value();
}

@ApplicationScoped
@SupportsJobType(JobType.A)
public class ServiceForA extends Service {
}
@ApplicationScoped
@SupportsJobType(JobType.B)
public class ServiceForB extends Service {
}

UPDATE:试图通过在SupportsJobType注释接口中包含SupportsJobTypeImpl来使其工作(如https://docs.jboss.org/cdi/api/2.0/javax/enterprise/util/AnnotationLiteral.html):

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface SupportsJobType {
JobType value();
public abstract class Literal extends AnnotationLiteral<SupportsJobType> implements SupportsJobType {
JobType requestedJobType;
public Literal() {
}

@Override
public JobType value() {
return requestedJobType;
}
@Override
public Class<? extends Annotation> annotationType() {
return SupportsJobType.class;
}
}
}

然而,我没有从ArC获得bean实例:

InstanceHandle<Service> instanceHandleA = Arc.container().instance(Service.class, new SupportsJobType.Literal() {
public JobType value() {
return JobType.A;
}
});

更新2:也不起作用:

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface SupportsJobType {
JobType value();
class Literal extends AnnotationLiteral<SupportsJobType> implements SupportsJobType {
JobType requestedJobType;
public Literal(JobType requestedJobType) {
this.requestedJobType = requestedJobType;
}
@Override
public JobType value() {
return requestedJobType;
}
@Override
public Class<? extends Annotation> annotationType() {
return SupportsJobType.class;
}
}
}

我没有从ArC得到任何bean实例:

InstanceHandle<Service> instanceHandleA = Arc.container().instance(Service.class, new SupportsJobType.Literal(JobType.A));

据我所知,你正在做的正是你应该做的。注释类型的实现嵌套在注释类型本身中,称为Literal并扩展AnnotationLiteral类是惯用的。例如(从内存中写入(:

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface SupportsJobType {
JobType value();
class Literal extends AnnotationLiteral<SupportsJobType> implements SupportsJobType {
private final JobType value;
public Literal(JobType value) {
this.value = value;
}
@Override
public JobType value() {
return value;
}
}
}

原来我被中提到的一个小细节绊倒了https://stackoverflow.com/a/66980506/753724这意味着我只需要将@Unremovable添加到bean中,就可以得到:

@ApplicationScoped
@Unremovable
@SupportsJobType(JobType.A)
public class ServiceForA extends Service {
}
@ApplicationScoped
@Unremovable
@SupportsJobType(JobType.B)
public class ServiceForB extends Service {
}

使用稍微调整过的Annotation类(只有新的静态方法(:

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface SupportsJobType {
JobType value();
class Literal extends AnnotationLiteral<SupportsJobType> implements SupportsJobType {
JobType requestedJobType;

public Literal(JobType requestedJobType) {
this.requestedJobType = requestedJobType;
}
public static Literal of(JobType value) {
return new Literal(value);
}
@Override
public JobType value() {
return requestedJobType;
}
@Override
public Class<? extends Annotation> annotationType() {
return SupportsJobType.class;
}
}
}

这些豆子是由发现的

InstanceHandle<Service> instanceHandleA = Arc.container().instance(Service.class, SupportsJobType.Literal.of(JobType.A));
InstanceHandle<Service> instanceHandleB = Arc.container().instance(Service.class, SupportsJobType.Literal.of(JobType.B));

最新更新