【问题标题】:cdi produce method ignoredcdi 生成方法被忽略
【发布时间】:2017-10-15 23:24:55
【问题描述】:

我正在尝试使用 cdi 注入从 application.properties 文件中获取属性。当我的字段被使用时,我的生产者方法永远不会被调用。所以他们总是为空。我错过了什么,做错了什么?

这是我的制作人课程:

propertyProducer

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import org.apache.log4j.Logger;

@ApplicationScoped
public class propertyProducer implements property{

    final static Logger logger = Logger.getLogger(propertyProducer.class);
    private Properties properties;

    @Property
    @Produces
    public String produceString(final InjectionPoint ip) {
        return this.properties.getProperty(getKey(ip));
    }

    @Property
    @Produces
    public int produceInt(final InjectionPoint ip) {
        return Integer.valueOf(this.properties.getProperty(getKey(ip)));
    }

    @Property
    @Produces
    public boolean produceBoolean(final InjectionPoint ip) {
        return Boolean.valueOf(this.properties.getProperty(getKey(ip)));
    }

    private String getKey(final InjectionPoint ip) {

        return (ip.getAnnotated().isAnnotationPresent(Property.class) && 
                !ip.getAnnotated().getAnnotation(Property.class).value().isEmpty()) ?
                ip.getAnnotated().getAnnotation(Property.class).value():ip.getMember().getName();

    }
    @PostConstruct

    public void init() {    
        this.properties = new Properties();
        final InputStream stream = propertyProducer.class.getResourceAsStream("/application.properties");  
        if (stream == null) {
            throw new RuntimeException("No properties!!!");
        }    
        try { 
            this.properties.load(stream);    
        } catch (final IOException e) { 
            throw new RuntimeException("Configuration could not be loaded!");   
        }   
    } 
}

我的界面

import javax.enterprise.util.Nonbinding;
import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

public interface property {
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Property {
    @Nonbinding String value() default "";
    @Nonbinding boolean required() default true;
    }
}

这是我通过字段获取注入属性的方式

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.kino.jax.property.Property;
import com.kino.jax.urlReader.URLReader;

@RequestScoped
public class caller implements callerInterface{

    @Inject
    @Property("appId")
    private String appId;

    @Inject
    @Property("devId")
    private String devId;

    @Inject
    @Property("certId")
    private String certId;

    @Inject
    @Property("ebayWsBaseUrl")
    private String ebayWsBaseUrl;

    @Inject
    @Property("ebayFindAndGetWsExtension")
    private String ebayFindAndGetWsExtension;

    @Inject
    @Property("ebayFindAndGetWsParam")
    private String ebayFindAndGetWsParam;


    final static Logger logger = Logger.getLogger(caller.class);
    //private int maxResults;
    private final int REQUEST_DELAY=500;

    @Override
    public void run(String search) throws Exception {
        logger.info("inside caller class");
        String address = createAddress(search);
        logger.info("sending request to :: "+ address);
        String response = URLReader.read(address);
        logger.info("response :: "+ response);
        processResponse(response); 
        //Honor rate limits - wait between results
        Thread.sleep(REQUEST_DELAY);
    }
    private String createAddress(String search){
    //substitute token
    logger.info("preparing ws URL ");
    try{
        String address = ebayWsBaseUrl+ebayFindAndGetWsExtension+ebayFindAndGetWsParam;
        address.replace("[appName]", appId);
        address.replace("[keyWords]",search);

        return address;
    }
    catch(Exception e){
        logger.fatal("could not get service property "+e);
        return null;
    }
}

还有我的 homeManager,我可以在其中引用调用者类

//some code
public void callWS(String search){
    callerInterface call = new caller();
        try {
               call.run(search);
            } catch (Exception e) {
                e.printStackTrace();
            }
       }
//some code

【问题讨论】:

  • 为什么propertyProducer 实现property?它不需要。要提供更多信息,您能否举例说明如何注入此字段?并获得对该类的引用?
  • @JohnAment 坦克你的答案,没有特殊原因 propertyProducer 实现属性。它只是为了测试它是否有效果。我编辑了我的问题,以便您可以看到我的文件是如何使用的。
  • 在限定符接口“Property”(大写)周围有一个接口“property”(小写)是什么意思?似乎不寻常。我会尝试消除它,看看它有什么效果。
  • 你如何获得caller的引用?
  • 看起来像 CDI 发现问题。如果您注入的属性为空,则可以确定您的 Caller 类不是由 CDI 管理的。 Caller 类档案中有 beans.xml 吗?你怎么称呼Caller类?

标签: java cdi


【解决方案1】:

问题是您手动实例化您的类。您需要在 bean 中保留对 caller 的引用。

如果您使用 CDI 1.1 并需要进行静态查找,您可以使用 CDI.current().select(callerInterface.class).get() 获取参考。否则你会@Inject callerInterface c

【讨论】:

  • 感谢使用注入调用者的引用@Injectprotected caller callerWS; 成功了
猜你喜欢
  • 2016-04-18
  • 2017-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-09
  • 2018-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多