@Service 标记的类不存在注释数据
我正在尝试实现解析器模式(策略模式)。
所以我有一个自定义注释 @PaymentTypeValue
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface PaymentTypeValue {
PaymentType[] value();
}
和 PaymentType
作为枚举类
public enum PaymentType{
CASH, CARD, NET_BANKING, UPI, WALLET;
}
,现在我有接口 PaymentService
public interface PaymentService {
void process();
}
并有它的 5 个实现,其中一个就像
@Service
@PaymentTypeValue({PaymentTypeValue.CASH})
public class CashPaymentService implements PaymentService {
@Override
void process(){
//some logic
}
}
我 现在问题出
@Component
public class PaymentServiceResolver {
private static final Logger log = getLogger(PaymentServiceResolver.class);
@Autowired
private List<PaymentService> paymentServices;
private final Map<PaymentType, PaymentService> paymentServiceMap = new EnumMap<>(PaymentType.class);
@PostConstruct
public void init() {
paymentServices.forEach(paymentService -> {
PaymentTypeValue annotation = paymentService.getClass().getAnnotation(PaymentTypeValue.class);
if (annotation != null && annotation.value() != null) {
PaymentType[] paymentTypes = annotation.value();
Arrays.stream(paymentTypes).forEach(paymentType -> {
paymentServiceMap.put(paymentType, paymentService);
});
} else {
log.error("paymentService {} is missing a necessary annotation",
paymentService.getClass().getName());
log.error("This paymentService cannot be initialized");
// throw new IllegalStateException("paymentService is missing a necessary annotation for " + paymentService.getClass().getName());
}
}
);
}
public PaymentService resolvePaymentService(PaymentType paymentType) {
PaymentService paymentService = paymentServiceMap.get(paymentType);
if (paymentService != null) {
return paymentService;
} else {
String message = "Could not find paymentService for " + paymentType;
log.error(message);
throw new RuntimeException(message);
}
}
}
在 init() 方法中,PaymentService 的所有服务实现都出现在列表中,但是当我尝试查找注释时,它给出了 null。 我检查了 paymentService.getClass() 方法的值,其中annotationData 有 0 个注释。如果我自动装配 PaymentService 的任何特定实现,那么我就能够获取注释值。请帮助我理解我在这里缺少什么?
I'm trying to implement resolver pattern ( strategy pattern ).
So I have one custom annotation @PaymentTypeValue
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface PaymentTypeValue {
PaymentType[] value();
}
and PaymentType
as enum class
public enum PaymentType{
CASH, CARD, NET_BANKING, UPI, WALLET;
}
now I have interface PaymentService
public interface PaymentService {
void process();
}
and have its 5 implementations, one is like
@Service
@PaymentTypeValue({PaymentTypeValue.CASH})
public class CashPaymentService implements PaymentService {
@Override
void process(){
//some logic
}
}
And I have resolver which is like this
@Component
public class PaymentServiceResolver {
private static final Logger log = getLogger(PaymentServiceResolver.class);
@Autowired
private List<PaymentService> paymentServices;
private final Map<PaymentType, PaymentService> paymentServiceMap = new EnumMap<>(PaymentType.class);
@PostConstruct
public void init() {
paymentServices.forEach(paymentService -> {
PaymentTypeValue annotation = paymentService.getClass().getAnnotation(PaymentTypeValue.class);
if (annotation != null && annotation.value() != null) {
PaymentType[] paymentTypes = annotation.value();
Arrays.stream(paymentTypes).forEach(paymentType -> {
paymentServiceMap.put(paymentType, paymentService);
});
} else {
log.error("paymentService {} is missing a necessary annotation",
paymentService.getClass().getName());
log.error("This paymentService cannot be initialized");
// throw new IllegalStateException("paymentService is missing a necessary annotation for " + paymentService.getClass().getName());
}
}
);
}
public PaymentService resolvePaymentService(PaymentType paymentType) {
PaymentService paymentService = paymentServiceMap.get(paymentType);
if (paymentService != null) {
return paymentService;
} else {
String message = "Could not find paymentService for " + paymentType;
log.error(message);
throw new RuntimeException(message);
}
}
}
Now the problem is in init() method, all the service implementations of PaymentService
are present in list but when i'm trying to find annotations its giving null.
I checked the value of paymentService.getClass()
method and in that annotationData had 0 annotations. If I autowire any specific implementation of PaymentService then I'm able to get the annotation value. Please help me understand what I'm missing here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
注释方法使事情变得复杂,我会尽力避免这种情况。没有注释的更简单的解决方案,假设 PaymentType 和服务实现之间存在 1:1 映射:
接口:
服务实现:
服务定位器:
您可以向解析器添加更多验证逻辑,以在 Spring 初始化阶段检查每个
PaymentType
是否有可用的实现。The annotation approach makes things complex, I would try to avoid that. A simpler solution without annotations, assuming that there is a 1:1 mapping between
PaymentType
and service implementation:boolean canHandle(PaymentType)
to the service interface.Interface:
Service implementation:
Service locator:
You may add more validation logic to your resolver to check during the Spring's initialization phase whether an implementation is available for each
PaymentType
.