ActiveJ ist eine moderne Java -Plattform, die von Grund auf gebaut wurde. Es ist so konzipiert, dass es autark ist (keine Abhängigkeiten von Drittanbietern), einfach, leicht und bietet eine Wettbewerbsleistung. ActiveJ besteht aus einer Reihe orthogonaler Bibliotheken, von Abhängigkeitsinjektion und leistungsstarker Asynchron-E/A (inspiriert von Node.js) bis hin zu Anwendungsservern und Big Data-Lösungen.
Diese Bibliotheken haben so wenige Abhängigkeiten wie möglich zueinander und können gemeinsam oder getrennt verwendet werden. ActiveJ in keinem weiteren Framework, das den Benutzer dazu zwingt, ihn auf all-oder-Nichts-Basis zu verwenden, aber stattdessen gibt er dem Benutzer so viel Freiheit wie möglich, um Bibliothekskomponenten für bestimmte Aufgaben auszuwählen.
ActiveJ besteht aus mehreren Modulen, die logisch in die folgenden Kategorien unterteilt werden können:
Async.io - Hochleistungs -Asynchron -IO mit der effizienten Ereignisschleife, NIO, Versprechen, Streaming und CSP. Alternative zu Netty, Rxjava, Akka und anderen. (Promise, EventLoop, Net, CSP, DataStream)
// Basic eventloop usage
public static void main ( String [] args ) {
Eventloop eventloop = Eventloop . create ();
eventloop . post (() -> System . out . println ( "Hello, world!" ));
eventloop . run ();
} // Promise chaining
public static void main ( String [] args ) {
Eventloop eventloop = Eventloop . builder ()
. withCurrentThread ()
. build ();
Promises . delay ( Duration . ofSeconds ( 1 ), "world" )
. map ( string -> string . toUpperCase ())
. then ( string -> Promises . delay ( Duration . ofSeconds ( 3 ))
. map ( $ -> "HELLO " + string ))
. whenResult ( string -> System . out . println ( string ));
eventloop . run ();
} // CSP workflow example
ChannelSuppliers . ofValues ( 1 , 2 , 3 , 4 , 5 , 6 )
. filter ( x -> x % 2 == 0 )
. map ( x -> 2 * x )
. streamTo ( ChannelConsumers . ofConsumer ( System . out :: println )); // Datastream workflow example
StreamSuppliers . ofValues ( 1 , 2 , 3 , 4 , 5 , 6 )
. transformWith ( StreamTransformers . filter ( x -> x % 2 == 0 ))
. transformWith ( StreamTransformers . mapper ( x -> 2 * x ))
. streamTo ( StreamConsumers . ofConsumer ( System . out :: println ));HTTP - Hochleistungs -HTTP -Server und Client mit WebSocket -Unterstützung. Es kann als einfacher Webserver oder als Anwendungsserver verwendet werden. Alternative zu anderen herkömmlichen HTTP -Clients und Servern. (Http)
// Server
public static void main ( String [] args ) throws IOException {
Eventloop eventloop = Eventloop . create ();
AsyncServlet servlet = request -> HttpResponse . ok200 ()
. withPlainText ( "Hello world" )
. toPromise ();
HttpServer server = HttpServer . builder ( eventloop , servlet )
. withListenPort ( 8080 )
. build ();
server . listen ();
eventloop . run ();
} // Client
public static void main ( String [] args ) {
Eventloop eventloop = Eventloop . create ();
HttpClient client = HttpClient . create ( eventloop );
HttpRequest request = HttpRequest . get ( "http://localhost:8080" ). build ();
client . request ( request )
. then ( response -> response . loadBody ())
. map ( body -> body . getString ( StandardCharsets . UTF_8 ))
. whenResult ( bodyString -> System . out . println ( bodyString ));
eventloop . run ();
}ActiveJ Inject - Leichte Bibliothek für die Abhängigkeitsinjektion. Optimiert für schnelle Anwendungsstart und Leistung zur Laufzeit. Unterstützt Annotationsbasiskomponentenkabel sowie reflexionsfreie Verkabelung. (ActiveJ Inject)
// Manual binding
public static void main ( String [] args ) {
Module module = ModuleBuilder . create ()
. bind ( int . class ). toInstance ( 101 )
. bind ( String . class ). to ( number -> "Hello #" + number , int . class )
. build ();
Injector injector = Injector . of ( module );
String string = injector . getInstance ( String . class );
System . out . println ( string ); // "Hello #101"
} // Binding via annotations
public static class MyModule extends AbstractModule {
@ Provides
int number () {
return 101 ;
}
@ Provides
String string ( int number ) {
return "Hello #" + number ;
}
}
public static void main ( String [] args ) {
Injector injector = Injector . of ( new MyModule ());
String string = injector . getInstance ( String . class );
System . out . println ( string ); // "Hello #101"
}BOOT - Produktionsbereite Tools zum Ausführen und Überwachen einer ActiveJ -Anwendung. Gleichzeitige Kontrolle des Dienstes für Dienstleistungen auf der Grundlage ihrer Abhängigkeiten. Verschiedene Dienstprogramme für Serviceüberwachung mit JMX- und Zabbix -Unterstützung. (Launcher, Service -Graph, JMX, Trigger)
public class MyLauncher extends Launcher {
@ Inject
String message ;
@ Provides
String message () {
return "Hello, world!" ;
}
@ Override
protected void run () {
System . out . println ( message );
}
public static void main ( String [] args ) throws Exception {
Launcher launcher = new MyLauncher ();
launcher . launch ( args );
}
}Bytecode -Manipulation
ActiveJ CodeGen - Dynamischer Bytecode -Generator für Klassen und Methoden neben der ObjectWEB ASM -Bibliothek. Zusammenfassung Die Komplexität der Direktbytecode-Manipulation und ermöglicht es Ihnen, benutzerdefinierte Klassen im laufenden Fliegen mit lisparischen AST-Ausdrücken zu erstellen. (ActiveJ CodeGen)
// Manually implemented method
public class MyCounter implements Counter {
@ Override
public int countSum () {
int sum = 0 ;
for ( int i = 0 ; i < 100 ; i ++) {
sum += i ;
}
return sum ;
}
} // The same method generated via ActiveJ Codegen
public static void main ( String [] args ) {
DefiningClassLoader classLoader = DefiningClassLoader . create ();
Counter counter = ClassGenerator . builder ( Counter . class )
. withMethod ( "countSum" ,
let ( value ( 0 ), sum ->
sequence (
iterate (
value ( 0 ),
value ( 100 ),
i -> set ( sum , add ( sum , i ))),
sum
)))
. build ()
. generateClassAndCreateInstance ( classLoader );
System . out . println ( counter . countSum ()); // 4950
}ActiveJ Serializer - schnelle und platzeffiziente Serialisierer, die mit Bytecode Engineering erstellt wurden. Führt einen schemafreien Ansatz für die beste Leistung ein. (ActiveJ Serializer)
// A class to be serialized
public class User {
private final int id ;
private final String name ;
public User ( @ Deserialize ( "id" ) int id , @ Deserialize ( "name" ) String name ) {
this . id = id ;
this . name = name ;
}
@ Serialize
public int getId () {
return id ;
}
@ Serialize
public String getName () {
return name ;
}
} // Serialization and deserialization
public static void main ( String [] args ) {
BinarySerializer < User > userSerializer = SerializerFactory . defaultInstance ()
. create ( User . class );
User john = new User ( 1 , "John" );
byte [] buffer = new byte [ 100 ];
userSerializer . encode ( buffer , 0 , john );
User decoded = userSerializer . decode ( buffer , 0 );
System . out . println ( decoded . id ); // 1
System . out . println ( decoded . name ); // John
} // Serialization of Java records
@ SerializeRecord
public record User ( int id , String name ) {
} // StreamCodec usage example
public static void main ( String [] args ) throws IOException {
StreamCodec < User > userStreamCodec = StreamCodec . create ( User :: new ,
User :: getId , StreamCodecs . ofVarInt (),
User :: getName , StreamCodecs . ofString ()
);
List < User > users = List . of (
new User ( 1 , "John" ),
new User ( 2 , "Sarah" ),
new User ( 3 , "Ben" )
);
ByteArrayOutputStream baos = new ByteArrayOutputStream ();
try ( StreamOutput streamOutput = StreamOutput . create ( baos )) {
for ( User user : users ) {
userStreamCodec . encode ( streamOutput , user );
}
}
ByteArrayInputStream bais = new ByteArrayInputStream ( baos . toByteArray ());
try ( StreamInput streamInput = StreamInput . create ( bais )) {
while (! streamInput . isEndOfStream ()) {
User decoded = userStreamCodec . decode ( streamInput );
System . out . println ( decoded . getId () + " " + decoded . getName ());
}
}
}ActiveJ Specializer - Innovative Technologie zur Verbesserung der Klassenleistung zur Laufzeit durch automatische Umwandlung von Klasseninstanzen in spezielle statische Klassen und Klasseninstanzfelder in statische Felder. Bietet eine Vielzahl von JVM -Optimierungen für statische Klassen, die sonst unmöglich sind: Dead Code Elimination, aggressive Einbeziehung von Methoden und statische Konstanten. (ActiveJ Specializer)
// Operators
public record IdentityOperator () implements IntUnaryOperator {
@ Override
public int applyAsInt ( int operand ) {
return operand ;
}
}
public record ConstOperator ( int value ) implements IntUnaryOperator {
@ Override
public int applyAsInt ( int operand ) {
return value ;
}
}
public record SumOperator ( IntUnaryOperator left , IntUnaryOperator right ) implements IntUnaryOperator {
@ Override
public int applyAsInt ( int operand ) {
return left . applyAsInt ( operand ) + right . applyAsInt ( operand );
}
}
public record ProductOperator ( IntUnaryOperator left , IntUnaryOperator right ) implements IntUnaryOperator {
@ Override
public int applyAsInt ( int operand ) {
return left . applyAsInt ( operand ) * right . applyAsInt ( operand );
}
} // Expression specialization
public static void main ( String [] args ) {
// ((x + 10) * (-5)) + 33
IntUnaryOperator expression = new SumOperator (
new ProductOperator (
new ConstOperator (- 5 ),
new SumOperator (
new ConstOperator ( 10 ),
new IdentityOperator ()
)
),
new ConstOperator ( 33 )
);
Specializer specializer = Specializer . create ();
expression = specializer . specialize ( expression );
System . out . println ( expression . applyAsInt ( 0 )); // -17
}Wolkenkomponenten
ActiveJ FS - Asynchrone Abstraktion über das Dateisystem zum Erstellen effizienter, skalierbarer lokaler oder Remote -Dateispeicher, die Datenreduktion, Neuausgleichung und Umformung unterstützen. (ActiveJ FS)
public static void main ( String [] args ) throws IOException {
Eventloop eventloop = Eventloop . builder ()
. withCurrentThread ()
. build ();
HttpClient httpClient = HttpClient . create ( eventloop );
ExecutorService executor = Executors . newCachedThreadPool ();
Path directory = Files . createTempDirectory ( "fs" );
FileSystem fileSystem = FileSystem . create ( eventloop , executor , directory );
String filename = "file.txt" ;
fileSystem . start ()
// Upload
. then (() -> fileSystem . upload ( filename ))
. then ( consumer -> httpClient . request ( HttpRequest . get ( "http://localhost:8080" ). build ())
. then ( response -> response . loadBody ())
. then ( body -> ChannelSuppliers . ofValue ( body ). streamTo ( consumer )))
// Download
. then (() -> fileSystem . download ( filename ))
. then ( supplier -> supplier . streamTo ( ChannelConsumers . ofConsumer ( byteBuf ->
System . out . println ( byteBuf . asString ( StandardCharsets . UTF_8 )))))
// Cleanup
. whenComplete ( executor :: shutdown );
eventloop . run ();
}ActiveJ RPC -Hochleistungs-Binär-Client-Server-Protokoll. Ermöglicht das Erstellen verteilter, verteilter und fehlertoleranter Microservice-Anwendungen. (ActiveJ RPC)
// Server
public static void main ( String [] args ) throws IOException {
Eventloop eventloop = Eventloop . create ();
RpcServer server = RpcServer . builder ( eventloop )
. withMessageTypes ( String . class )
. withHandler ( String . class , name -> Promise . of ( "Hello, " + name ))
. withListenPort ( 9000 )
. build ();
server . listen ();
eventloop . run ();
} // Client
public static void main ( String [] args ) {
Eventloop eventloop = Eventloop . create ();
RpcClient client = RpcClient . builder ( eventloop )
. withStrategy ( RpcStrategies . server ( new InetSocketAddress ( 9000 )))
. withMessageTypes ( String . class )
. build ();
client . start ()
. then (() -> client . sendRequest ( "John" ))
. whenResult ( response -> System . out . println ( response )) // "Hello, John"
. whenComplete ( client :: stop );
eventloop . run ();
}Verschiedene zusätzliche Dienste: ActiveJ CRDT, Redis Client, Memcache, Olap Cube, DataFlow
Fügen Sie diesen Ausschnitt in Ihr Terminal ein ...
mvn archetype:generate -DarchetypeGroupId=io.activej -DarchetypeArtifactId=archetype-http -DarchetypeVersion=6.0-beta2
... und öffnen Sie das Projekt in Ihrer Lieblings -IDE. Erstellen Sie dann die Anwendung und führen Sie sie aus. Öffnen Sie Ihren Browser in Localhost: 8080, um die Nachricht "Hello World" zu sehen.
public final class HttpHelloWorldExample extends HttpServerLauncher {
@ Provides
AsyncServlet servlet () {
return request -> HttpResponse . ok200 ()
. withPlainText ( "Hello, World!" )
. toPromise ();
}
public static void main ( String [] args ) throws Exception {
Launcher launcher = new HttpHelloWorldExample ();
launcher . launch ( args );
}
}Einige technische Details zum obigen Beispiel:
Um mehr über ActiveJ zu erfahren, besuchen Sie bitte https://activej.io oder folgen Sie unserem 5-minütigen Get-Started-Leitfaden.
Beispiele für die Verwendung der ActiveJ -Plattform und alle ActiveJ -Bibliotheken finden Sie im examples .
Versionshinweise für ActiveJ finden Sie hier