Java 使用带焊接的EL分解器时,如何解决类型差异?
我有一个通用的EL生成器,我编写它是为了利用WELD的能力,在需要时“使其工作”,甚至将类型强制写入函数中,以确保返回类型与WELD注入点匹配 我的问题是: WELD从注入点的可分配类型解析,即,如果注入点是字符串,它将只查找具有字符串返回类型的生产者 这是有问题的,因为我需要一个生产者来处理类型强制,并返回一个正确类型的对象 作为一个kludge,我有一个字符串生成器方法,它别名为真正的生成器,并且只执行kluding类型 这个。。。至少是有效的,直到我有了一个对象类型的注入点,在这个点上,我所有的kludge方法和泛型生产者都是匹配的,给出了一个模糊的依赖异常,即使我在生产者上使用@typed 有没有一个明智的方法来解决这个问题,或者我应该放弃让WELD为我做所有艰苦工作的想法 下面是一个使用该生产者的示例,来自一个具有请求范围的错误处理bean。RequestURI是一个在这种情况下很麻烦的方法,其他两个需要类型化的“kludge”方法才能工作。这个特定bean(不包括代码)的主要功能是捕获未处理的异常,并通过电子邮件向我们报告,以便在将来的修订版中进行更具体的错误处理。这里的基本用例是简化对EL的编程访问,并可能允许使用值绑定写回EL,尽管这在这个特定代码中是不可能的 我知道我可以用其他方法来做下面的事情,这不是重点。实际上,以编程方式访问EL是一件积极的事情,特别是在处理JSF2.0引入的一些更奇特的作用域(特别是Flash作用域)时。我的大多数用例都与Flash scope有关,但在这里披露并不安全,它们也不是可预测的类型,或者应该为它们编写乱码的类型,因此我希望使用这种更通用的方法Java 使用带焊接的EL分解器时,如何解决类型差异?,java,jsf,el,cdi,jboss-weld,Java,Jsf,El,Cdi,Jboss Weld,我有一个通用的EL生成器,我编写它是为了利用WELD的能力,在需要时“使其工作”,甚至将类型强制写入函数中,以确保返回类型与WELD注入点匹配 我的问题是: WELD从注入点的可分配类型解析,即,如果注入点是字符串,它将只查找具有字符串返回类型的生产者 这是有问题的,因为我需要一个生产者来处理类型强制,并返回一个正确类型的对象 作为一个kludge,我有一个字符串生成器方法,它别名为真正的生成器,并且只执行kluding类型 这个。。。至少是有效的,直到我有了一个对象类型的注入点,在这个点上,我
@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;
}
}
}
我知道我可以使用其他工具完成以下操作
方法,这不是重点
我真的很努力,但我没有设法不评论您正在失去类型安全性(这是CDI的主要设计目标之一),EL评估是性能杀手…;-)
无论如何,我(几乎没有)说过:
没有真正的CDI选项来克服这一问题。我建议您为那些EL表达式使用特定类型,如ElObject
等等,它由生产者构造,并且它本身为客户端提供类型安全的访问器
编辑:您可能想看看,它以一种简洁的方式提供EL功能 你能描述一下你想要达到的目标吗?EL注入的一个或两个示例用法非常好。Seam焊料功能非常接近我想要的,只是错过了在注入时自动完成这一操作的最后一步。这可能是我目前能得到的最接近的结果,所以我很感激这个建议。
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)
...