ActiveJは、ゼロから構築されたモダンなJavaプラットフォームです。自給自足(サードパーティの依存関係なし)、シンプルで軽量であるように設計されており、競争力のあるパフォーマンスを提供します。 ActiveJは、依存関係の注入と高性能の非同期I/O(node.jsに触発)、アプリケーションサーバー、ビッグデータソリューションまで、さまざまな直交ライブラリで構成されています。
これらのライブラリは、互いに可能な限り依存関係が少なく、一緒にまたは別々に使用できます。 ActiveJは、ユーザーがすべてまたは無効なベースで使用することを強制する別のフレームワークではなく、特定のタスクのライブラリコンポーネントを選択するという点でできるだけ多くの自由をユーザーに提供します。
ActiveJは、次のカテゴリに論理的にグループ化できます。
async.io-効率的なイベントループ、nio、Promises、Streaming、およびCSPを使用した高性能非同期IO。 Netty、Rxjava、Akkaなどに代わるもの。 (約束、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- WebSocketサポートを備えた高性能HTTPサーバーとクライアント。単純なWebサーバーとして、またはアプリケーションサーバーとして使用できます。他の従来のHTTPクライアントおよびサーバーに代わるもの。 (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注入- 依存噴射のための軽量ライブラリ。ランタイムでの高速アプリケーションの起動とパフォーマンス用に最適化されています。注釈ベースのコンポーネント配線と反射のない配線をサポートします。 (ActiveJ注入)
// 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"
}ブート- ActiveJアプリケーションを実行および監視するための生産対応ツール。依存関係に基づいたサービスライフサイクルの同時制御。 JMXおよびZabbixサポートを備えたさまざまなサービス監視ユーティリティ。 (ランチャー、サービスグラフ、JMX、トリガー)
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 );
}
}バイトコード操作
ActiveJ CodeGen -ObjectWeb ASMライブラリの上にあるクラスとメソッド用の動的バイトコードジェネレーター。直接バイトコード操作の複雑さを抽象化し、LISPのようなAST式を使用して、その場でカスタムクラスを作成できるようにします。 (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 -ByteCodeエンジニアリングで作成された高速および空間効率の高いシリアイザー。最高のパフォーマンスのためのスキーマフリーのアプローチを紹介します。 (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-クラスインスタンスを特殊な静的クラスとクラスインスタンスフィールドに自動的に変換して、クラスインスタンスフィールドに焼き付けの静的フィールドに自動的に変換することにより、実行時にクラスのパフォーマンスを向上させるための革新的なテクノロジー。それ以外の場合は不可能な静的クラスのさまざまなJVM最適化を提供します:死んだコードの除去、方法の積極的なインライン、および静的定数。 (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
}クラウドコンポーネント
ActiveJ FS-ファイルシステム上の非同期抽象化は、データの冗長性、リバランス、および再シャードをサポートする効率的でスケーラブルなローカルまたはリモートファイルストレージを構築します。 (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-高性能バイナリクライアントサーバープロトコル。分散、シャード、およびフォールトトレラントマイクロサービスアプリケーションの建物を許可します。 (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 ();
}さまざまな追加サービス:ActiveJ CRDT、Redisクライアント、MEMCACHE、OLAPキューブ、データフロー
このスニペットをターミナルに貼り付けます...
mvn archetype:generate -DarchetypeGroupId=io.activej -DarchetypeArtifactId=archetype-http -DarchetypeVersion=6.0-beta2
...そして、お気に入りのIDEでプロジェクトを開きます。次に、アプリケーションを構築して実行します。 LocalHost:8080でブラウザを開き、「Hello World」メッセージを表示します。
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 );
}
}上記の例に関するいくつかの技術的な詳細:
ActiveJの詳細については、https://activej.ioにアクセスするか、5分間のゲットスタートガイドをフォローしてください。
ActiveJプラットフォームとすべてのActiveJライブラリを使用する例は、 examplesモジュールにあります。
ActiveJのリリースノートはここにあります