gpt4 book ai didi

java - 将 EL 解析器与 WELD 结合使用时,如何解决类型差异?

转载 作者:行者123 更新时间:2023-12-01 15:52:51 27 4
gpt4 key购买 nike

我有一个通用的 EL 生成器,我编写它是为了利用 WELD 的能力,在我需要它时“使其工作”,甚至将类型强制写入函数中,以确保返回类型与焊接注入(inject)点匹配。

这是我的问题:WELD 从注入(inject)点的可分配类型解析,即,如果您的注入(inject)点是 String,它只会查找具有 String 返回类型的生产者。

这是有问题的,因为我想要一个生产者来处理类型强制,并返回一个正确类型的对象。

作为一个拼凑,我有一个字符串生成器方法,它是真正的生成器的别名,并且只进行类型拼凑。

这......至少有效,直到我遇到对象类型注入(inject)点的情况,此时我的所有组装方法和通用生产者都匹配,给出了不明确的依赖异常,即使我在生产者上使用@Typed。

是否有一个明智的方法可以解决这个问题,或者我应该放弃让 WELD 为我完成所有艰苦工作的想法?

下面是使用此生成器的示例,来自具有 Request 作用域的错误处理 bean。 RequestURI 是这种情况下比较麻烦的一个,另外两个需要键入“kludge”方法才能工作。这个特定 bean(不包括代码)的主要功能是捕获未处理的异常并通过电子邮件将其报告给我们,以便在将来的修订中进行更具体的错误处理。这里的基本用例是简化对 EL 的编程访问,并可能允许使用值绑定(bind)写回 EL,尽管在此特定代码中这是不可能的。

我知道我可以使用其他方法执行以下操作,但这不是重点。实际上,在 IMO 中以编程方式访问 EL 变得更容易是一件积极的事情,特别是在处理 JSF 2.0 引入的一些更奇特的作用域(尤其是 Flash 作用域)时。我的大多数用例都与 Flash 作用域有关,但在这里披露并不安全,它们也不是可预测的类型,也不是应该为它们编写的拼凑的类型,因此我想要这种更通用的方法。

   @Inject
@ELResource("#{requestScope['javax.servlet.error.exception']}")
protected Exception exception;

@Inject
@ELResource("#{requestScope['javax.servlet.error.status_code']}")
protected String statusCode;

@Inject
@ELResource("#{requestScope['javax.servlet.error.request_uri']}")
protected Object requestUri;

这是我的限定符:

@Target(value = {ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER})
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
@Qualifier
public @interface ELResource {
@Nonbinding
String value();
}

制作人:

@Dependent
public class ELProducer {

@Inject
FacesContext facesContext;

@Inject
Logger log;

@Produces
@ELResource("")
public Object getELResource(InjectionPoint ip) {
log.entering(getClass().getName(), "getELResource()",new Object[] {ip});

ExpressionFactory expFactory = facesContext.getApplication().getExpressionFactory();
String elString = ip.getAnnotated().getAnnotation(ELResource.class).value();
Class coercionType = resolveClass(ip);

log.log(Level.INFO, "EL String: {0} of type: {1}", new Object[] {elString, coercionType.getName()});
if (elString == null || elString.length() <= 0) {
log.log(Level.SEVERE,"No EL String specified for injection");
log.exiting(getClass().getName(), "getELResource()");
return null;
}

ValueExpression ve = expFactory.createValueExpression(facesContext.getELContext(), elString, coercionType);

if (ve != null) {
Object retval = ve.getValue(facesContext.getELContext());
log.log(Level.INFO,"EL Result: {0} of type: {1}",new Object[] { retval, ((retval != null) ? retval.getClass().getName() : "NULL") } );
log.exiting(getClass().getName(), "getELResource()",new Object[] {retval} );
return retval;
} else {
log.log(Level.WARNING,"Null EL Result");
log.exiting(getClass().getName(), "getELResource()");
return null;
}
}

// TODO: There should be a better way of accomplishing the below
@Produces
@ELResource("")
public String getELStringResource(InjectionPoint ip) {
return (String)getELResource(ip);
}

@Produces
@ELResource("")
public Exception getELExceptionResource(InjectionPoint ip) {
return (Exception)getELResource(ip);
}

private Class resolveClass(InjectionPoint ip) {
Annotated annotated = ip.getAnnotated();
Member member = ip.getMember();

if (member instanceof Field) {
Field field = (Field)member;
return field.getType();
} else if (member instanceof Constructor) {
Constructor con = (Constructor)member;
AnnotatedParameter ap = (AnnotatedParameter)annotated;
return con.getParameterTypes()[ap.getPosition()];
} else if (member instanceof Method) {
Method method = (Method)member;
AnnotatedParameter ap = (AnnotatedParameter)annotated;
return method.getParameterTypes()[ap.getPosition()];
} else {
return null;
}

}
}

错误:

org.jboss.weld.exceptions.DeploymentException: WELD-001409 Ambiguous dependencies for type [Object] with qualifiers [@ELResource] at injection point [[field] @Inject @ELResource protected xxx.backing.ErrorHandler.requestUri]. Possible dependencies [[Producer Method [Exception] with qualifiers [@Any @ELResource] declared as [[method] @Produces @Typed @ELResource public xxx.ELProducer.getELExceptionResource(InjectionPoint)], Producer Method [String] with qualifiers [@Any @ELResource] declared as [[method] @Produces @Typed @ELResource public xxx.ELProducer.getELStringResource(InjectionPoint)], Producer Method [Object] with qualifiers [@Any @ELResource] declared as [[method] @Produces @Dependent @ELResource public xxx.ELProducer.getELResource(InjectionPoint)]]]
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:309)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:139)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:162)
...

最佳答案

I know I can do the below using other methods, that's not the point.

我真的很努力,但我没有设法没有评论你正在失去类型安全(这是CDI的主要设计目标之一), EL 评估是性能 killer ......;-)

无论如何,(几乎没有)说了这样的话:

没有真正的 CDI 选项可以克服这个问题。我建议您为这些 EL 表达式使用特定类型,例如 ElObject 等,它由生产者构造,本身为客户端提供类型安全访问器。

编辑:您可能想查看 Seam Solder ,它以一种简洁的方式提供 EL 功能...

关于java - 将 EL 解析器与 WELD 结合使用时,如何解决类型差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5672214/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com