ActiveJ هي منصة Java الحديثة التي تم بناؤها من الألف إلى الياء. إنه مصمم ليكون مكتفيًا ذاتيًا (لا تبعيات الطرف الثالث) ، بسيطة وخفيفة الوزن وتوفر أداءًا تنافسيًا. يتكون ActiveJ من مجموعة من المكتبات المتعامدة ، من حقن التبعية و I/O غير المتزامن عالي الأداء (مستوحاة من Node.js) ، إلى خوادم التطبيق وحلول البيانات الضخمة.
هذه المكتبات لديها أقل عدد ممكن من التبعيات فيما يتعلق ببعضها البعض ويمكن استخدامها معًا أو بشكل منفصل. ليس ActiveJ في إطار آخر يجبر المستخدم على استخدامه على أساس كل شيء أو لا شيء ، ولكنه بدلاً من ذلك يمنح المستخدم أكبر قدر ممكن من الحرية من حيث اختيار مكونات المكتبة لمهام معينة.
يتكون ActiveJ من عدة وحدات ، والتي يمكن تجميعها منطقيا في الفئات التالية:
Async.io - IO غير المتزامن عالي الأداء مع حلقة الأحداث الفعالة ، NIO ، الوعود ، البث ، و CSP. بديل عن 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 - خادم HTTP عالي الأداء والعميل مع دعم WebSocket. يمكن استخدامه كخادم ويب بسيط أو كخادم تطبيق. بديل لعملاء وخوادم 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"
}Boot - أدوات جاهزة للإنتاج لتشغيل ومراقبة تطبيق 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 );
}
}التلاعب Bytecode
ActiveJ Codegen - مولد Bytecode الديناميكي للفئات والأساليب أعلى مكتبة ObjectWeb ASM. الملخصات تعقيد معالجة Bytecode المباشر ويسمح لك بإنشاء فئات مخصصة على الطيران باستخدام تعبيرات AST تشبه lisp. (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 - التكنولوجيا المبتكرة لتحسين الأداء الصف في وقت التشغيل من خلال تحويل مثيلات الفصل تلقائيًا إلى فئات ثابتة متخصصة وحقول مثيلات الفصل في الحقول الثابتة المخبوزة. يوفر مجموعة واسعة من تحسينات JVM للفئات الثابتة المستحيل خلاف ذلك: القضاء على الكود الميت ، وضمان العدوانية للطرق والثوابت الثابتة. (تخصص ActiveJ)
// 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 Client ، Memcache ، OLAP Cube ، DataFlow
الصق هذا المقتطف في المحطة الخاصة بك ...
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 هنا