// I would want to turn this...
public final class Handler
{
private final Session session;
@Inject
public Handler(@Named("Database") final Session session)
{
this.session = session;
}
...
}
// into something like this...
public final class Handler
{
private final Session session;
@Inject
public Handler(final Session session)
{
this.session = session;
}
}
// where "session" is injected based on some previous context value ("Database")
// or something to that effect.
我最后使用了HK2中的一个名为Operations(指向文档的链接)的功能。它允许HK2的用户定义自定义范围,并将其管理为“操作”。您可以在HK2的github项目中找到如何使用该功能的更详细示例:operations example。
这是一个简化的例子,说明了我最终是如何使用这个特性来基于上下文或在本例中是“范围”来注入东西的。
下面是一些几乎可以工作的伪代码来演示我的用法:
// Create the custom scope annotation.
@Scope
@Proxiable(proxyForSameScope = false)
@Documented
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface BatchScope
{
public static final BatchScope INSTANCE = new BatchScopeEnvoy();
}
final class BatchScopeEnvoy extends AnnotationLiteral<BatchScope> implements BatchScope
{
private static final long serialVersionUID = 938233179310254573L;
}
// Create a context used by the HK2 operation feature.
@Singleton
public final class BatchScopeContext extends OperationContext<BatchScope>
{
@Override
public Class<? extends Annotation> getScope()
{
return BatchScope.class;
}
}
// Create a class that holds your custom scope data/context.
public final class BatchScopeRuntime
{
// ... Arbitrary runtime data here ...
public SomeData getData()
{
return this.data;
}
}
// Create a factory that serves up something you want to inject from a custom scope.
@Singleton
public final class DataFactory implements Factory<SomeData>
{
private final OperationManager operations;
@Inject
public BatchInfoFactory(final OperationManager operations)
{
Sentinel.assertIsNotNull(operations);
this.operations = operations;
}
// The @BatchScope on the provide() method indicates that objects returned
// from this factory are in the "BatchScope".
@Override
@BatchScope
public IBatchInfo provide()
{
final OperationHandle handle = this.operations.getCurrentOperation(BatchScope.INSTANCE);
final BatchScopeRuntime runtime = (BatchScopeRuntime)handle.getOperationData();
return runtime.getData();
}
@Override
public void dispose(final IBatchInfo instance)
{
// Do nothing.
}
}
// Setup the injector.
public static ServiceLocator createInjector(final String name)
{
final ServiceLocator injector = ServiceLocatorFactory.getInstance().create(name);
ServiceLocatorUtilities.bind(
injector,
new AbstractBinder()
{
@Override
protected void configure()
{
// This creates a "Singleton" factory that provides
// "SomeData" instances at "BatchScope".
bindFactory(DataFactory.class, Singleton.class)
.to(SomeData.class)
.in(BatchScope.class);
}
}
return injector;
}
// Create a class that needs something in the custom scope.
public final class Foo
{
@Inject
public Foo(final SomeData data)
{
System.out.printf("I got: %s%n", data);
}
}
// Usage: how to manage the scopes using the operations feature.
final SomeData data = ... // get some data
final BatchScopeRuntime runtime = new BatchScopeRuntime(data); // Setup the runtime information.
// Create an operation handle for the custom scope and associate the custom data with it.
final ServiceLocator injector = createInjector("test");
ServiceLocatorUtilities.addClasses(injector, BatchScopeContext.class, Foo.class);
final OperationManager operations = injector.getService(OperationManager.class);
final OperationHandle<BatchScope> batchScope = operations.createAndStartOperation(BatchScope.INSTANCE);
// Operation/scope is now associated with the current thread.
batchScope.setOperationData(runtime);
// Foo will now be injected with: "data" from above.
final Foo foo = injector.getService(Foo.class);
// Do some work...
// Close the operation (make it go out of scope) on the current thread.
batchScope.closeOperation();
作为CDI的新手,我想知道替代方案和限定符之间的实际区别。 在焊缝参考中,它指出: 4.3. 限定符注释 如果我们有多个实现特定bean类型的bean,注入点可以使用限定符注释精确指定应该注入哪个bean。 但在解释替代方案时,据说: 4.7.备选方案 替代方案是bean,其实现特定于特定的客户端模块或部署场景。 如果我理解正确的话,@Qualifier定义了目标bean的哪些实现被注入到注入点。
我试图找出CDI和适合我需要的最佳方法。我有一个与普通tcp通信交互的服务()。现在这个服务有一些地方需要通知某人发生了什么事情。对于这些信息,我有接口,需要将其CDI注入到正确的实现中。另一个问题是服务本身被注入一个作业()中,该作业定期执行并调用服务来完成任务。这意味着服务将多次存在。每个都有它处理的另一个tcp连接,并且有另一个需要在接口中注入另一个驱动程序/协议的设备。 让我展示参与此场景
问题内容: 我试图了解下限和上限通配符的行为。 尝试编译以下代码时遇到问题。 为了弄清楚问题,我还尝试了下限通配符。幸运的是或不幸的是,代码可以很好地编译,但是却造成了很多混乱。 有人可以解释一下这两个代码段如何工作。如果有人可以提供其他示例/链接,那就太好了。 如果我在上面做错了什么,请纠正我。 提前致谢。 问题答案: 表示“未知类型”。 表示某种对象的集合。此“某种类型”可以是作为其子类或自身
我需要根据应用程序执行的环境(开发、测试、生产等)改变JDBC连接的注入方式。新环境的添加必须易于处理。因此,考虑到佩莱格里尼对以下问题的解决方案,我试图实施这种行为: 多个CDI配置文件(devel,beta,qa,生产)在一个战争? 注射点是这样的: 我有两个连接工厂: ConnectionFactory:用于测试、验收和生产环境; ProxyConnectionFactory:仅适用于开发环
假设有一个SessionFactory的生产者(举个例子): 不,我可以这样使用我的数据库对象: 到目前为止,一切都很好。因此,让我们假设这些东西是在一个框架中实现的,并且将被几个应用程序使用。 现在,一个应用程序决定使用另一个SessionFactory,因此它实现了自己的生产者和一个限定符:
我有一个平面文件连接,它在SSIS包中加载文本文件。Visual Studio有时坚持在连接管理器上添加文本限定符,即使我删除了它。当添加此文本限定符时,将跳过文件中的最后一条记录,因此会导致问题。我需要一种方法来确保文件总是工作,有或没有这个限定符。既然我是以编程方式创建这些文件,那么它需要如何结束才能使限定符不影响它呢?我尝试用\r\n结束文件,但似乎没有解决问题。