【问题标题】:CDI alternatives with priority not working as expected? What would be the possible cause?具有优先权的 CDI 替代品未按预期工作?可能的原因是什么?
【发布时间】:2017-08-16 07:31:10
【问题描述】:

当我尝试用priority 试验CDI alternatives 时,它的工作方式相反,选择优先级最低的bean 而不是优先级最高的bean。具有优先权的替代方案如何运作?

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
    bean-discovery-mode="all">
    <alternatives>
        <class>org.bala.java.jee.cdi.alternatives.priority.entity.RegularGreeting</class>
        <class>org.bala.java.jee.cdi.alternatives.priority.entity.FancyGreeting</class>
        <class>org.bala.java.jee.cdi.alternatives.priority.entity.PriorityGreeting</class>
    </alternatives>
</beans>

Greeting.java

package org.bala.java.jee.cdi.alternatives.priority.entity;

    public interface Greeting {

        public String greet(final String greet);

    }

FancyGreeting.java

package org.bala.java.jee.cdi.alternatives.priority.entity;

import javax.annotation.Priority;
import javax.enterprise.inject.Alternative;
import javax.interceptor.Interceptor;

@Alternative
@Priority(Interceptor.Priority.APPLICATION + 1)
public class FancyGreeting implements Greeting {

    @Override
    public String greet(String greet) {
        return "schöner Tag,  " + greet;
    }        
}

PriorityGreeting.java

package org.bala.java.jee.cdi.alternatives.priority.entity;

import javax.annotation.Priority;
import javax.enterprise.inject.Alternative;
import javax.interceptor.Interceptor;

@Alternative
@Priority(Interceptor.Priority.APPLICATION + 2)
public class PriorityGreeting implements Greeting {

    @Override
    public String greet(String greet) {
        return "der Vorrang, Hello, " + greet;
    }
}

RegularGreeting.java

package org.bala.java.jee.cdi.alternatives.priority.entity;

import javax.annotation.Priority;
import javax.enterprise.inject.Alternative;
import javax.interceptor.Interceptor;

@Alternative
@Priority(Interceptor.Priority.APPLICATION)
public class RegularGreeting implements Greeting {

    @Override
    public String greet(String greet) {
        return "hello " + greet;
    }
}

AlternativesPriorityController.java

 package org.bala.java.jee.cdi.alternatives.priority.controller;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

    import org.bala.java.jee.cdi.alternatives.priority.entity.Greeting;

    @ApplicationScoped
    public class AlternativesPriorityController {

        @Inject
        Greeting greet;

        public String getGreet(String string) {
            return greet.greet(string);
        } 
    }

AlternativesPriorityResource.java

package org.bala.java.jee.cdi.alternatives.priority.boundary;

import javax.inject.Inject;
import javax.json.Json;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;

    import javax.ws.rs.core.Response;

    import org.bala.java.jee.cdi.alternatives.priority.controller.AlternativesPriorityController;

    @Path("/alternatives")
    public class AlternativesPriorityResource {

        @Inject
        AlternativesPriorityController controller;

        @Path("/priority")
        @GET
        public Response getGreet() {
            return Response.ok(Json.createObjectBuilder().add("Greet", controller.getGreet("Princess !")).build(), MediaType.APPLICATION_JSON).build();
        }
    }

输出:

{
  "Greet": "hello Princess !"
}

但是想要的输出是,

    {
      "Greet": "der Vorrang, Hello, Princess !"
    }

谢谢。

按照@BalusC 的建议更新了beans.xml

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
    bean-discovery-mode="all"> 
</beans>

【问题讨论】:

    标签: jakarta-ee cdi


    【解决方案1】:

    这是因为您在beans.xml 中也注册了它们,而RegularGreeting 排名最高。 XML 配置总是覆盖注解配置。换句话说,@Alternative 完全被忽略了。

    只需从beans.xml 中删除整个&lt;alternatives&gt; 部分,然后@Alternative 就可以与@Priority 一起完成它的工作。

    【讨论】:

    • 我尝试从beans.xml 中删除整个alternatives 部分,但仍然选择了优先级最低的bean (RegularGreeting) 而不是高优先级的bean (PriorityGreeting)
    • 我正在使用 Payara Full 版本 4.1.2
    • 在干净的构建和重新部署之后,按预期工作,虽然在 payara 中启用了自动发布,但我必须在 eclipse 中以旧方式部署它。谢谢@BalusC
    • @BalusC 稍微修正一下,XML 配置并不总是覆盖优先级注释。这实际上是由规范未定义的,由实施决定。您观察到的是特定于焊接的行为。
    • @Siliarus:任何其他可注释的 Java EE 容器托管工件都可以通过一些 XML 文件覆盖,例如 CDI 托管 bean (beans.xml)、JSF 工件 (faces-config.xml)、JPA 实体 ( orm.xml)、EJB 拦截器 (ejb.xml)、WebServlets/Filters/Listeners (web.xml) 等。对于其中的大多数,它甚至是明确指定的。这允许在外部覆盖带注释的行为,而无需重新构建应用程序。如果实现者决定做相反的事情,我会感到惊讶,因为这会使应用程序无法在外部配置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多