我一直在学习Java EE,发现Java EE提供了两种类型的注入机制
请指导我理解资源注入和依赖注入之间的区别.
在hibernate挂接我的JBoss AS 7.1之前,我试图在我的应用程序中运行flyway.我尝试使用@javax.ejb.Startup注释,但是在初始化Hibernate并检查数据库方案之后执行此操作.
所以据我所知,我们可以使用CDI扩展,它在初始化Hibernate之前挂钩.对飞路的开箱即用有什么支持吗?如果没有,有没有人试过这样做呢?
我想创建一个Producer,它可以将java.util.ResourceBundle注入任何类,以便轻松获取本地化的Strings.我的ResourceBundle-Producer看起来像这样:
public class ResourceBundleProducer {
@Inject
public Locale locale;
@Inject
public FacesContext facesContext;
@Produces
public ResourceBundle getResourceBundle() {
return ResourceBundle.getBundle("/messages", locale )
}
}
Run Code Online (Sandbox Code Playgroud)
Locale和FacesContext的注入工作(从Seam 3 Alpha Source获取相应的生产者).但不幸的是,ResourceBundle不是Serializable,因此不能以这种方式生成.当我试图访问一个调用使用我的ResourceBundle的bean的JSF页面时,我从Weld得到以下错误:
Caused by: org.jboss.weld.IllegalProductException: WELD-000054 Producers cannot produce non-serializable instances for injection into non-transient fields of passivating beans\\n\\nProducer\: org.jboss.weld.bean-/D:/Program Files (x86)/GlassFish-Tools-Bundle-For-Eclipse-1.2/glassfishv3/glassfish/domains/teachernews/applications/teachernews/-ProducerMethod-services.producers.ResourceBundleProducer.getResourceBundle()\\nInjection Point\: field web.PersonHome.bundle
有没有办法让我的ResourceBundleResolver工作?或者是否有其他机制来获得类似的功能?提前致谢!
编辑:
好的,我将花费一些我几乎没有得到的积分;)也会接受一个很好的解决方法来解决这个问题!
我有另一个例子,创建一个Producer不起作用:一个FlashProducer.还无法生成FacesContext-Flash,因为Flash不可序列化.
我正在尝试处理@ManagedProperty但没有成功!
我一直在关注这个指南,看起来并不难.但我的代码根本行不通!
这是一个小片段
@ManagedBean
@SessionScoped
public class LoginBean {
@EJB
private LoginUserLocal loginUser;
private boolean loggedIn = false;
private User user;
private StreamedContent image;
.
.
.
//--
@Named(value = "messagesBean")
@RequestScoped
public class MessagesBean {
@ManagedProperty(value = "#{loginBean}")
private LoginBean loginBean;
public LoginBean getLoginBean() {
return loginBean;
}
public void setLoginBean(LoginBean loginBean) {
this.loginBean = loginBean;
}
public String getUser() {
System.err.println(loginBean == null);
return loginBean.getUser().getUsername();
}
Run Code Online (Sandbox Code Playgroud)
这段代码给了我一个NullPointerException,说loginBean为null!
有什么建议吗?
我用CDI做了一个小测试项目.我的应用程序由EJB EAR和WAR组成,全部部署在Glassfish 4上.我正在使用Hibernate 4.3.4来访问数据库.
我的目标是验证EJB(DAO)中的类是否可以接收EntityManager的注入.
SessionBean + EJB模式并不是很棒,但我必须修改已经创建的应用程序,所以我没有太多选择.
这是我的EJB代码:
@Named
public class DAOTest implements Serializable {
private static final long serialVersionUID = 1L;
@PersistenceContext(unitName="CDI-ejb")
private EntityManager em;
public void test(){
//em.getClass();
}
public EntityManager getEm() {
return em;
}
public void setEm(EntityManager em) {
this.em = em;
}
public DAOTest() {
// TODO Auto-generated constructor stub
}
}
Run Code Online (Sandbox Code Playgroud)
Service.java
@Stateless
@LocalBean
public class Service implements ServiceLocal {
@Inject DAOTest test;
/**
* Default constructor.
*/
public Service() {
// TODO …Run Code Online (Sandbox Code Playgroud) 我喜欢Guice如此直接地手动创建自己的模块的方式,每个模块都有自己的代码绑定.另一方面,CDI似乎更多地依赖于魔术而不是程序化访问sest绑定.我错了,或者如何用WELD达到同样的效果.
任何代码示例将不胜感激......
我希望使用Guice在http://code.google.com/p/google-guice/上提供的构建器模式样式,以编程方式构建一个模块(Guice术语,我不确定CDI术语).
我正在构建一个动态系统,我需要能够绑定类型(如接口),常量等,而不仅仅是让Weld动态扫描类路径等并查找和注册类型.我相信CDI是静态的,javax.inject包不包含允许以编程方式将类型绑定到实现的任何接口.
原始问题的基本前提是简单的观察,即注释被烘焙,并且在其中定义的规则可以帮助无法更改注释器.我最初希望公共访问CDI类路径扫描程序用于构建内部使用定义的相同接口.基本上我说的是,我想要一个允许我读取注释并为容器创建定义的图层.默认提供程序可以是执行现在发生的操作的提供程序,但如果您需要其他策略,则可以执行此操作.
当前方法的一个问题是不能重用具有不同注释的组件(类)来选择不同的协作者的限制.在您跳转之前让我对此声明进行限定,是的,可以通过提供商等来完成,但这会导致更多的工件.应该有一个更简单的方法.
很抱歉,如果这个例子不好,我的用例就会更加复杂,细节也会受到阻碍,并且需要更长时间的阅读.
想象一下有一个url重写组件,为了论证,有一些参数,如
如果您希望使用两个不同的替换规则注入相同的组件但是使用html清洁器注入器,则卡住了.当然有办法解决这个问题,但他们需要人工制品,这当然是更多的代码.
遗憾的是,所有绑定规则都在类而不是实例上,因此每次你要求一个类时,你都会得到几乎相当于实例的实例.
这个问题是在一段时间之前写的,我已经放弃了Weld.我相信它决定魔术如何完成的方式是错误的.我不喜欢这样的事实,即如果没有为我提供控制何时或如何重复此操作的方法,他们会向我发出这种情况.我不喜欢这种不灵活性.
在CDI中,您可以使用以下命令定义一个对象,该对象将为您提供特定类型的项目:
@Inject Instance<MyObject> myObjectInstance; //... MyObject myObjectInstance.get();
同样在Guice中你可以做到:
@Inject Provider<MyObject> myObjectInstance; //... MyObject myObjectInstance.get();
我想知道Spring中是否有类似的构造,或者你必须使用它ApplicationContext才能获得引用?
是否可以使用CDI将参数注入方法调用?预期的行为类似于现场注入.查找首选生产者并使用产品.
我想做的是:
public void foo(@Inject Bar bar){
//do stuff
}
Run Code Online (Sandbox Code Playgroud)
或者这个(使用较少混淆的sytax):
public void foo(){
@Inject
Bar bar;
//do stuff
}
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,此语法都是非法的 还有其他选择吗?如果不是 - 如果有可能,出于某种原因,这会是一个坏主意吗?
谢谢
编辑 - 我可能已经使我的要求不够清楚 - 我希望能够直接调用该方法,将bar变量的初始化留给容器.JörnHorstmann和Perception的回答表明这是不可能的.
Java EE7由一堆"bean"定义组成:
为了摆脱我心中的混乱,我研究了几篇"何时使用哪种豆类"的文章.EJB的一个优点似乎是它们单独支持声明性容器管理事务(着名的事务注释).不过,我不确定这是否正确.任何人都可以批准这个吗?
同时,我想出了一个简单的演示应用程序来检查这是否真的如此.我刚刚根据这个片段定义了一个CDI bean(不是 EJB - 它没有类级别注释),如下所示:
public class CdiBean {
@Resource
TransactionSynchronizationRegistry tsr;
@Transactional(Transactional.TxType.REQUIRED)
public boolean isTransactional() {
return tsr.getTransactionStatus() == Status.STATUS_ACTIVE;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,GlassFish 4.0的结果是这个方法实际上返回true,根据我的询问,它没有按预期工作.我确实希望容器忽略CDI bean方法上的@Transactional注释,或者甚至抛出异常.我使用新安装的GlassFish 4服务器,因此没有干扰.
所以我的问题是:
(顺便说一句:有人在这里描述了类似的问题,但其解决方案并不适用于我的情况.
我正在开发一个应用程序,我已经开始使用CDI沿JSF和JPA.Web容器是Tomcat.
我EntityManager对我的CDI豆子里的生命周期非常困惑,我需要一个很好的建议来清除我心中的一些东西.一般来说,我读过的是EntityManager主要应该在Java EE容器中使用,使用PersistenceContext注释注入它.因此,容器会照顾它的生命.但是,如果你不使用Java EE容器(as Tomcat),那么我需要管理我EntityManager的生活.
使用哪个是我最好的选择Tomcat, CDI, JSF and JPA?我现在正在做的是以下内容:
public class EntityManagerFactoryProducer {
public static final String TEST = "test";
@Produces
@ApplicationScoped
public EntityManagerFactory create() {
return Persistence.createEntityManagerFactory(TEST);
}
public void destroy(@Disposes
EntityManagerFactory factory) {
factory.close();
}
}
public class EntityManagerProducer {
@Inject
private transient Logger logger;
@Inject
private EntityManagerFactory emf;
@Produces
public EntityManager …Run Code Online (Sandbox Code Playgroud)