在不使用@Inject / @ EJB的情况下从@Entity访问@Singleton

时间:2014-08-20 08:43:14

标签: java ejb domain-driven-design

我使用域驱动设计(我认为!),我需要访问一些全局属性。我有@Singleton因此:

@Singleton
public class MyProperties {
    private Properties props;

    @PostConstruct
    private void initialize()
    {
        try {
            props.load(new FileInputStream("my.properties"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public String getProperty(String propertyName)
    {
        return props.getProperty(propertyName);
    }
}

我想这样做:

@Entity(name="MYENTITY")
public class MyEntity {
    @Inject private MyProperties props;
    void doSomething()
    {
        String myProp = props.getProperty("my-prop");
        // ...etc...
    }
}

但是,这不起作用 - propsnull,无论如何网站告诉我not to do that,我应该use a Service Locator instead,但所有的气味都是使用EJB 3.x kills off

的JNDI查找

我的计划可能是尝试这种事情:

@WebListener
public class MyServletContextListener implements ServletContextListener{
    @Inject private MyProperties props;
    private MyServletContextListener theInstance;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        theInstance = this;
    }

    static public MyServletContextListener theInstance() { return theInstance; }
    public MyProperties getProperties() { return props; }
}

这是否有意义,或者我是在咆哮错误的树,还是我的代码中只有一些愚蠢的错误?

编辑:请注意我使用带有CDI,JPA等的vanilla Java EE,没有Spring。

EDIT2 :我看到CDI最佳实践说应该add the @Vetoed annotation to all persistent entities。目前我的应用程序流控制是从@MessageBean到一系列@Entity - 这是一种设计气味吗?

3 个答案:

答案 0 :(得分:0)

首先,任何你的实体都不在spring应用程序的上下文中,所以,任何spring的bean都不能注入你的实体! 其次,如果你真的想这样做,请添加:

<context:spring-configured />

进入spring配置,然后在MyEntity类中添加@Configurable!

答案 1 :(得分:0)

好吧,我破解了我尊敬的Gang of Four book并意识到我在这里有一个访客模式,这在我的@Entity构成一个层次结构时特别有用。所以,我会添加这样的代码:

public class DoSomethingVisitor extends EntityVisitor {
    @Inject private MyProperties props;

    @Override
    void visit(MyEntity entity)
    {
        String myProp = props.getProperty("my-prop");
        if(entity.getValue().equals(myProp))
        //...or whatever...
    }
}

@Entity(name="MYENTITY")
public class MyEntity {
    void Accept(EntityVisitor visitor)
    {
        visitor.visit(this);
    }
}

此解决方案还允许我删除logger调用后传递的doSomething()参数,而我的业务逻辑现在已超出@Entity并进入我可以注射的地方。

答案 2 :(得分:0)

如果您选择了一种javaee方式,我认为在这种情况下,优先使用上面的@EntityListener注释实体。这个怎么运作。使用例如@PostConstruct@PrePersist注释的一些方法定义一个侦听器类:

    public class DoSomethingVisitor {

     @PrePersist  
     void visit(MyEntity entity)
    {
        String myProp = props.getProperty("my-prop");
        if(entity.getValue().equals(myProp))
        //...or whatever...
    }

    }

并在实体的注释中定义此类:

@Entity(name="MYENTITY")
@EntityListeners(value = {DoSomethingVisitor.class})
public class MyEntity {
    void Accept(EntityVisitor visitor)
    {
        visitor.visit(this);
    }
}

javaee框中已包含所有最佳模式!