我有一个用于本地化的属性文件:
foo=Bar
title=Widget Application
Run Code Online (Sandbox Code Playgroud)
这与resource-bundlefaces-config中的a相关:
<resource-bundle>
<base-name>com.example.messages.messages</base-name>
<var>msgs</var>
</resource-bundle>
Run Code Online (Sandbox Code Playgroud)
我可以使用EL在facelets视图中访问它:
<title>#{msgs.title}</title>
Run Code Online (Sandbox Code Playgroud)
但是,如果有像SQLExceptions这样的东西,我需要能够从托管bean编写消息.这一切都有效:
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "There was an error saving this widget.", null);
FacesContext.getCurrentInstance().addMessage(null, message);
Run Code Online (Sandbox Code Playgroud)
这是问题所在:我希望这些消息来自属性文件,以便它们也可以根据区域设置进行更改.有没有一种简单的方法来使用注入访问属性文件?
我想对一些基于CDI的项目有自己的背景.我需要(想要)自定义范围,以便我可以隔离组件的生存时间和位置.
为了实现自己的情况下,你需要实现Context接口,这是相当不言自明,但在创建时如何或在哪里,你真的确定?
假设我有两个类,首先是一个没有任何属性,字段或注释的类:
public class B {}
Run Code Online (Sandbox Code Playgroud)
和一个注入B的类,如下所示:
public class A {
@Inject
private B b;
public B getB() {
return b;
}
}
Run Code Online (Sandbox Code Playgroud)
现在A级在我们使用之前是没用的,所以有两种选择:
如果A被注入,CDI管理它并且足够注入B,其具有隐含的@Dependent范围.很酷,就是我想要的.
但是,如果我手动构造A(假设在工厂或构建器中),CDI完全忽略我的对象并且不会注入类型B的对象.
示例我在谈论它什么时候不起作用,这里对象a将始终保持为null:
public class Builder {
@Inject
private A a;
public static Builder ofTypeSomething() {
// do some magic here
return new Builder();
}
private Builder() {
// and some more here
}
}
Run Code Online (Sandbox Code Playgroud)
为什么这不起作用?
A类是一个有效的托管bean,并且有一个有效的范围,就像B类一样.即使我将@Producer添加到静态方法,它也不会改变任何东西(这很好,因为静态方法的想法是调用它,不要在任何地方注入Builder).
我正在尝试使用BeanManager而不是Instance .select().get()创建CDI托管bean的实例.
这被建议作为我已经使用ApplicationScoped bean和他们的家属的垃圾收集的问题的解决方法 - 请参阅CDI应用程序和依赖范围可以合谋影响垃圾收集?对于背景和建议的解决方法.
如果在ApplicationScoped bean上使用Instance编程查找方法,Instance对象和从中获取的任何bean最终都依赖于ApplicationScoped bean,因此共享它的生命周期.但是,如果使用BeanManager创建bean,则会在Bean实例本身上设置句柄,并且显然可以明确地销毁它,我理解这意味着它将被GCed.
我目前的方法是在BeanManagerUtil类中创建bean,并返回Bean,实例和CreationalContext的复合对象:
public class BeanManagerUtil {
@Inject private BeanManager beanManager;
@SuppressWarnings("unchecked")
public <T> DestructibleBeanInstance<T> getDestructibleBeanInstance(final Class<T> type,
final Annotation... qualifiers) {
DestructibleBeanInstance<T> result = null;
Bean<T> bean = (Bean<T>) beanManager.resolve(beanManager.getBeans(type, qualifiers));
if (bean != null) {
CreationalContext<T> creationalContext = beanManager.createCreationalContext(bean);
if (creationalContext != null) {
T instance = bean.create(creationalContext);
result = new DestructibleBeanInstance<T>(instance, bean, creationalContext);
}
}
return result;
}
}
public class DestructibleBeanInstance<T> {
private T instance;
private Bean<T> …Run Code Online (Sandbox Code Playgroud) 我正在使用Weld SE在我的应用程序中使用CDI.由于某些库可能具有@Inject注释,并且不希望让Weld扫描所有库.因此,我想在beans.xml中排除某些包前缀:
<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"
version="1.1" bean-discovery-mode="all">
<scan>
<exclude name="com.**" />
<exclude name="org.**" />
<exclude name="io.**" />
<exclude name="groovy.**" />
</scan>
</beans>
Run Code Online (Sandbox Code Playgroud)
但在执行时我收到以下错误:
2014-05-26T17:02:49.855 - INFO - Version - WELD-000900: SNAPSHOT
2014-05-26T17:02:50.340 - WARN - Bootstrap - WELD-001208: Error when validating jar:file:/home/trichner/uepaa/uepaa-net/cloud/target/unet-cloud-0.1-SNAPSHOT-jar-with-dependencies.jar!/META-INF/jboss-beans.xml@19 against xsd. cvc-elt.1: Cannot find the declaration of element 'deployment'.
2014-05-26T17:02:50.408 - INFO - Bootstrap - WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
2014-05-26T17:02:50.477 - WARN …Run Code Online (Sandbox Code Playgroud) 所以,我有一个使用Weld 1.2进行依赖注入的基本Java SE程序.
一切正常,直到我将Hibernate放入混合中,并使用以下pom.xml依赖项:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se</artifactId>
<version>2.2.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.6.Final</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
Hibernate是添加的依赖项,使其中断.这是我的入门课程:
public class EntryPoint {
public static void main( String[] ARGV ) {
Weld weld = new Weld();
WeldContainer container = weld.initialize();
Application application = container.instance().select(Application.class).get();
application.testFetch();
weld.shutdown();
}
}
Run Code Online (Sandbox Code Playgroud)
当我在包含Hibernate依赖项后尝试运行它时,这是我的输出:
Sep 11, 2014 11:13:44 PM org.jboss.weld.bootstrap.WeldStartup <clinit>
INFO: WELD-000900: 2.2.4 (Final)
Sep 11, 2014 11:13:44 PM org.jboss.weld.bootstrap.WeldStartup startContainer
INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. …Run Code Online (Sandbox Code Playgroud) 我创建了一个Java项目作为其他项目的lib,减少了项目之间的代码重复.此lib项目导出到jar以包含在Web项目中(WAR,而不是EAR).
在Web项目中(这些类被删除的地方)一切正常,而所有类都保留在它们上面 - 注入简单和复杂的对象(具有生产者和设置的对象)正常工作.
删除这些类的Web项目并将具有这些相同类的jar添加到Web项目(在Maven项目中的pom.xml中设置此lib)之后,所有内容都会正常编译,就像之前一样.但是在启动服务器时,容器在CDI启动期间找不到现在存在于jar中的类(CDI bean),从而产生这个(着名的)错误:
WELD-001408: Unsatisfied dependencies for type Session with qualifiers (...)
Run Code Online (Sandbox Code Playgroud)
已经在src/main/resources(在WELD和CDI文档中指出)的META-INF文件夹中添加了beans.xml作为项目的根文件夹.
下面是jar中需要注入其他项目的bean(Session,SessionFactory和ExampleLogger)的示例(并且在类在Web项目中时已正常工作)但现在CDI 尚未发现:
public class HibernateConnectionFactory {
@Produces
@ApplicationScoped @ConnectionBaseExample
public SessionFactory createSessionFactoryExample() {
Configuration configuration = new Configuration();
configurarSessionFactory(configuration, "baseExampleDS");
ServiceRegistry registry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
return configuration.buildSessionFactory(registry);
}
@Produces
@RequestScoped @ConnectionBaseExample
public Session createSessionExample(@ConnectionBaseExample SessionFactory sessionFactory) {
return sessionFactory.openSession();
}
public void destruirSessionExemplo(@Disposes @ConnectionBaseExample Session session) {
if (session.isOpen()) {
session.close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
public class ExampleLoggerProducer { …Run Code Online (Sandbox Code Playgroud) 我需要在Servlet中修改用户会话对象(SessionScoped bean-CDI),所以我必须以某种方式获取该bean.我用以下方式注射:
@Inject
private UserSession user;
Run Code Online (Sandbox Code Playgroud)
UserSession是SessionScoped CDI bean.用户方法是从doPost或doGet servlet方法调用的.这很完美; 每次@Inject注释都会注入相应的UserSession bean,但我不明白这种行为是如何实现的.
我假设用@Inject注释的bean只注入一次(当创建对象 - 本例中的Servlet实例时),但这显然是错误的假设.
那么,这些bean什么时候注入到servlet中?按要求?当有多个UserSession对象时,这种方法如何避免冲突(一个servlet实例 - 处理它的多个线程)?
我正在使用Java EE 6,需要从".properties"文件加载配置.是否有推荐的方法(最佳实践)使用依赖注入从配置文件加载值?我在Spring中找到了这个注释,但我还没有找到Java EE的"标准"注释.
这家伙从头开发了一个解决方案:
"我找不到一个简单的例子,说明如何通过从文件中读取配置属性来配置CDI应用程序......"
但我想知道是否有更标准的方法而不是创建配置工厂......
configuration annotations dependency-injection cdi java-ee-6
我想在Java-SE应用程序中使用拦截器,并且将焊接用作CDI实现,并且在这里进行测试:
主班:
public static void main(String[] args) {
WeldContainer weldContainer = new Weld().initialize();
Service service = weldContainer.instance().select(Service.class).get();
service.methodCall();
service.methodCallNumberTwo();
}
Run Code Online (Sandbox Code Playgroud)
服务等级:
public class Service {
@TestAnnotation
public void methodCall(){
System.out.println("methodCall...!");
methodCallNumberTwo();
}
@TestAnnotation
public void methodCallNumberTwo(){
System.out.println("methodCallNumberTwo...!");
}
}
Run Code Online (Sandbox Code Playgroud)
拦截器类:
@Interceptor
@TestAnnotation
public class TestInterceptor {
@AroundInvoke
public Object interceptorMethod(InvocationContext invocationContext) throws Exception {
System.out.println("I'm the TestInterceptor of "+invocationContext.getMethod());
return invocationContext.proceed();
}
}
Run Code Online (Sandbox Code Playgroud)
Aaa和输出:
I'm the TestInterceptor of public void Service.methodCall()
methodCall...!
methodCallNumberTwo...!
I'm the TestInterceptor of public void Service.methodCallNumberTwo() …Run Code Online (Sandbox Code Playgroud) cdi ×10
java ×5
weld ×4
java-ee ×2
jboss-weld ×2
jsf-2 ×2
managed-bean ×2
maven ×2
annotations ×1
hibernate ×1
interceptor ×1
java-ee-6 ×1
jsf ×1
scope ×1
servlets ×1