我试图找出CDI和适合我需要的最佳方法。我有一个与普通tcp通信交互的服务(TcpServiceImpl
)。现在这个服务有一些地方需要通知某人发生了什么事情。对于这些信息,我有接口TcpConnection
,需要将其CDI注入到正确的实现中。另一个问题是服务TcpServiceImpl
本身被注入一个作业(TcpConnectionJob
)中,该作业定期执行并调用服务来完成任务。这意味着服务TcpServiceImpl
将多次存在。每个都有它处理的另一个tcp连接,并且有另一个需要在接口中注入另一个驱动程序/协议的设备TcpConnection
。
让我展示参与此场景的三个要素:
以下是将获得多个实现的接口:
public interface TcpConnection
{
/**
* Connected.
*
* @throws NGException the NG exception
*/
public void connected() throws NGException;
/**
* This method will send the received data from the InputStream of the connection.
*
* @param data the received data
* @throws NGException the NG exception
*/
public void received( byte[] data ) throws NGException;
/**
* Usable for the protocol to send data to the device.
*
* @param data the data to send to the device ( Will be converted to byte[] with getBytes() )
* @throws NGException the NG exception
*/
public void send( String data ) throws NGException;
/**
* Usable for the protocol to send data to the device.
*
* @param data the data to send to the device ( Will be send as is )
* @throws NGException the NG exception
*/
public void send( byte[] data ) throws NGException;
/**
* This method will inform the protocol that the connection got closed.
*
* @throws NGException the NG exception
*/
public void closed() throws NGException;
}
另外,下面是在我的现有服务中何时调用此函数的示例片段:
public class TCPServiceImpl implements TCPService, Runnable
{
/** The callback. */
private TcpConnection callback;
private void disconnect()
{
connection.disconnect();
if ( !getStatus( jndiName ).equals( ConnectionStatus.FAILURE ) )
{
setStatus( ConnectionStatus.CLOSED );
}
/* TODO: Tell driver connection is closed! */
callback.closed();
}
}
下面是调用服务的类,然后需要为接口动态注入正确的实现。
public class TcpConnectionJob implements JobRunnable
{
/** The service. */
private TCPService service;
public void execute()
{
service.checkConnection( connection );
}
}
服务注入回调
必须链接到将转换数据或处理设备逻辑的正确“协议”或“驱动程序”的实现。接口将有多个不同的驱动程序实现,我需要注入正确的驱动程序实现。此决定的限定符可以是设备的名称。现在我看了以下链接:
理解CDI中类型安全的必要性
如何以编程方式查找和注入CDI托管bean,其中限定符包含类的名称
如何在多个类实现中使用CDI限定符?
问题:
但我仍然不确定使用哪种方式/方法以及正确的方式是什么。任何帮助都将不胜感激。
我的第一个想法是将我的接口复制到一个限定符接口,并在这个接口的后面添加输入限定符的可能性。这是个好主意吗?
这就是我想出的解决方案。现在唯一的问题是得到一个工作回调,但那是不同的。以下是对我有效的解决方案:
/**
* The Qualifier interface TcpDriver. The value of this annotation is the name the implementation
* is found under. Please only enter values that are configured in the wildfly config as the name of
* the device.
*/
@Documented
@Qualifier
@Retention( RUNTIME )
@Target( { TYPE, FIELD, METHOD, PARAMETER } )
public @interface TcpDriver
{
/**
* Value.
*
* @return the string
*/
String value();
}
仅针对限定符接口的默认实现:
/**
* The Class TcpDriverImpl.
*/
public class TcpDriverImpl extends AnnotationLiteral<TcpDriver> implements TcpDriver
{
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
/** The name. */
private final String name;
/**
* Instantiates a new tcp driver impl.
*
* @param name the name
*/
public TcpDriverImpl( final String name )
{
this.name = name;
}
/** {@inheritDoc} */
@Override
public String value()
{
return name;
}
}
现在有一个测试实现来测试它:
@TcpDriver( "terminal1" )
@Dependent
public class TestDriverImpl implements TcpConnection
{
/** The log. */
private Log log;
@Inject
public void init( Log log )
{
this.log = log;
}
@Override
public void connected() throws NGException
{
// TODO Auto-generated method stub
log.info( "IT WORKS!!" );
}
@Override
public void received( byte[] data ) throws NGException
{
// TODO Auto-generated method stub
}
@Override
public void send( String data ) throws NGException
{
// TODO Auto-generated method stub
}
@Override
public void send( byte[] data ) throws NGException
{
// TODO Auto-generated method stub
}
@Override
public void closed() throws NGException
{
// TODO Auto-generated method stub
log.info( "BYE BYE" );
}
}
最后但并非最不重要的一点是,我将所有这些注入到我的服务中的方式:
/** The callback Instance for the driver to find. */
@Inject
@Any
private Instance<TcpConnection> callback;
private TcpConnection driver;
/**
* Inject driver.
*/
private void injectDriver()
{
final TcpDriver driver = new TcpDriverImpl( name );
this.driver = callback.select( driver ).get();
}
我希望这能帮助那些和我有同样要求的人。
PS:如果您在测试实现中检查日志输出,然后查看日志,那么可以使用一个小日志来显示它的工作原理:)
2017-02-28 08:37:00,011 INFO starting TCPConnection: TcpDevice1 with status: NOT_CONNECTED
2017-02-28 08:37:00,018 INFO initializing terminal1
2017-02-28 08:37:00,019 INFO Creating socket for: terminal1 with port: XXXXX
2017-02-28 08:37:00,023 INFO Updated Status to CONNECTED for connection TcpDevice1
2017-02-28 08:37:00,024 INFO opened connection to terminal1
2017-02-28 08:37:00,026 INFO (terminal1) IT WORKS!!
2017-02-28 08:37:00,038 INFO (terminal1) terminal1: In threaded method run
2017-02-28 08:37:00,039 INFO (terminal1) waiting for data...
2017-02-28 08:39:00,045 INFO (terminal1) Socket closed!
2017-02-28 08:39:00,045 INFO (terminal1) BYE BYE
使用CDI事件,不要使用回调阻塞。一些资源:
https://docs.oracle.com/javaee/7/tutorial/cdi-adv005.htm
http://www.adam-bien.com/roller/abien/entry/java_ee_6_observer_with
http://www.next-presso.com/2014/06/you-think-you-know-everything-about-cdi-events-think-again/
问题内容: 我正试图让nvidia-docker在我的centos7系统上运行: 到目前为止,一切都很好: 现在,让我们尝试使用nvidia运行时: 但是奇怪的是 问题答案: 所以…最后,我完全禁用了selinux并重新启动,并对其进行了修复。
另一个,如果我有另一个应用程序使用相同的使用者组,所有的分区会被重新分配到该应用程序吗?
我对shell脚本和ssh命令等特别陌生。我想知道我是否可以在从一台服务器上载/下载文件到另一台服务器时自动执行简单的sftp提示。 以下是我的工作: 命令:sftpusername@ServerHost 我基本上希望实现自动化,因为我将调用一个脚本,该脚本将通过源服务器上的InfoSphere Datastage序列作业将文件从源服务器上传到远程服务器。 请原谅我的无礼,如果这个问题没有意义,如
我正在尝试使用Glassfish 4.0的最新升级版运行一个特别简单的测试用例。我已经尝试将META-INF/beans.xml放在所有可能的排列中,包括它自己在WEB-INF/lib中的jar 我得到的最好的结果是以下错误,后面列出了布局来源: 布局: < code>beans.xml的源: 的源代码: < code>Test.java的源代码: 的来源:
本文向大家介绍在Python中自动执行PDF,包括了在Python中自动执行PDF的使用技巧和注意事项,需要的朋友参考一下 使用的模块: 在此脚本中,我们将使用PyPDF2模块,该模块将为我们提供各种功能,例如提取数据,读取pdf文件,拆分文件并写入新文件。 下载PyPDF2: 通用方式:pip安装PyPDF2 Pycharm用户:转到python项目解释器并从那里安装它。 PyPDF2提供的各种
本文向大家介绍在Windows启动时自动运行Python脚本?,包括了在Windows启动时自动运行Python脚本?的使用技巧和注意事项,需要的朋友参考一下 将Python脚本添加到Windows启动时,基本上表示Python脚本将在Windows启动时运行。这可以通过两步过程来完成- 步骤#1:在Windows启动文件夹中添加或添加脚本 在启动Windows后,它会执行(相当于双击)其启动文件