Ich versuche CDI und die beste Methode zu finden, die meinen Bedürfnissen entspricht. Ich habe einen Dienst (TcpServiceImpl
), der mit einfacher TCP-Kommunikation interagiert. Jetzt hat dieser Dienst einige Punkte, an denen er jemanden darüber informieren muss, dass etwas passiert ist. Für diese Informationen habe ich die Schnittstelle TcpConnection
, die CDI in die richtige Implementierung injiziert werden muss. Ein anderes Problem ist, dass der Dienst TcpServiceImpl
selbst in einen Job (TcpConnectionJob
) eingefügt wird, der periodisch ausgeführt wird und den Dienst anruft, um Dinge zu tun. Das bedeutet, dass der Service TcpServiceImpl
mehrfach vorhanden ist. Jeder hat eine andere tcp-Verbindung, die er behandelt und ein anderes Gerät hat, das einen anderen Treiber/Protokoll benötigt, um in die Schnittstelle TcpConnection
injiziert zu werden.Injectind Implementierung automatisch zur Laufzeit über CDI
Lassen Sie zeigen mir die drei Elemente Teil in diesem Szenario unter:
Hier ist die Schnittstelle, die mehrere Implementierungen erhalten wird:
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;
}
Auch hier ist ein Beispiel-Snippet, wenn dies in heißen mein bestehender Service:
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();
}
}
Unten ist die Klasse, die den Dienst aufruft, die dann die korrekte Umsetzung dynamisch injizieren muss für die Schnittstelle.
public class TcpConnectionJob implements JobRunnable
{
/** The service. */
private TCPService service;
public void execute()
{
service.checkConnection(connection);
}
}
Der Service Injektion callback
muss die Umsetzung des richtigen „Protokoll“ oder „Treiber“ verknüpft werden, die die Daten verarbeiten oder die Logik für das Gerät übersetzen. Es wird mehrere Treiber-Implementierungen der Schnittstelle geben, die anders funktionieren und ich muss die richtige injizieren. Ein Qualifier für diese Entscheidung könnte der Name des Geräts sein. Nun schaute ich auf die folgenden Links:
Understanding the necessity of type Safety in CDI
How to use CDI qualifiers with multiple class implementations?
Frage:
Aber ich bin immer noch unsicher, welchen Weg/Methode zu verwenden, und was ist das richtiger Weg. Jede Hilfe wäre willkommen.
Mein erster Gedanke war, meine Schnittstelle zu einer Qualifier-Schnittstelle zu kopieren und diese mit der Möglichkeit anzufügen, den Qualifier einzugeben. Ist das eine gute Idee?
Leider kann ich nicht CDI Events verwenden. Ich wollte es ursprünglich so machen, aber da von der Anwendung eine große Menge an Datenverkehr und Daten erwartet wird, wurde meine Empfehlung abgelehnt. Soweit ich weiß, sind Ereignisse synchron, so dass das Auslösen eines Ereignisses dazu führt, dass das Programm darauf wartet, dass alle Beobachter beendet sind, bis weiterer Code ausgeführt wird. Was aber, wenn ich während der Benachrichtigung anderer über eingehende Daten aufpassen muss, dass Daten eintreffen? – Nico
@Nico: Werfen Sie einen Blick auf diesen interessanten Artikel, der erklärt, wie Sie CDI Event Asynchronous machen können. Es kann eine Lösung für Sie sein: http://piotrowicki.com/2013/05/asynchronous-cdi-events/ – Rouliboy
Vielen Dank für Ihren Artikel. Wirklich gut zu wissen und ich werde es speichern, aber ich würde gerne über eine Lösung nachdenken, ohne CDI-Ereignisse zu verwenden. Sagen wir es ist nicht möglich wegen der Ablehnung von jemandem. Meine Gedanken waren, irgendwie einen Produzenten in Kombination mit einem Qualifier zu erschaffen. Ist das eine gültige Strategie? – Nico