ActiveJ เป็นแพลตฟอร์ม Java ที่ทันสมัยที่สร้างขึ้นจากพื้นดิน มันถูกออกแบบมาให้พึ่งพาตนเองได้ (ไม่มีการพึ่งพาบุคคลที่สาม) เรียบง่ายน้ำหนักเบาและให้ประสิทธิภาพการแข่งขัน ActiveJ ประกอบด้วยช่วงของห้องสมุด orthogonal ตั้งแต่การฉีดพึ่งพาและ I/O แบบอะซิงโครนัสประสิทธิภาพสูง (ได้รับแรงบันดาลใจจาก Node.js) ไปจนถึงเซิร์ฟเวอร์แอปพลิเคชันและโซลูชั่นข้อมูลขนาดใหญ่
ห้องสมุดเหล่านี้มีการพึ่งพาน้อยที่สุดเท่าที่จะเป็นไปได้ด้วยความเคารพซึ่งกันและกันและสามารถใช้ร่วมกันหรือแยกกัน ActiveJ ยังไม่ได้กรอบอื่นที่บังคับให้ผู้ใช้ใช้มันบนพื้นฐานทั้งหมดหรือไม่มีอะไรเลย แต่มันจะให้อิสระแก่ผู้ใช้ให้มากที่สุดเท่าที่จะเป็นไปได้ในแง่ของการเลือกส่วนประกอบห้องสมุดสำหรับงานเฉพาะ
ActiveJ ประกอบด้วยหลายโมดูลซึ่งสามารถจัดกลุ่มอย่างมีเหตุผลเป็นหมวดหมู่ต่อไปนี้:
ASYNC.IO - IO แบบอะซิงโครนัสประสิทธิภาพสูงด้วย Event Event Loop, Nio, สัญญา, สตรีมมิ่งและ CSP ทางเลือกสำหรับ Netty, Rxjava, Akka และอื่น ๆ (สัญญา, eventloop, net, csp, dataastream)
// 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 Inject - ห้องสมุดที่มีน้ำหนักเบาสำหรับการฉีดพึ่งพา ปรับให้เหมาะสมสำหรับการเริ่มต้นแอปพลิเคชันที่รวดเร็วและประสิทธิภาพที่รันไทม์ รองรับการเดินสายส่วนประกอบที่ใช้คำอธิบายประกอบรวมถึงการเดินสายที่ปราศจากการสะท้อน (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 - เครื่องมือพร้อมการผลิตสำหรับการรันและตรวจสอบแอปพลิเคชัน ActiveJ การควบคุมวงจรชีวิตการบริการพร้อมกันตามการพึ่งพาของพวกเขา ยูทิลิตี้การตรวจสอบบริการต่างๆด้วยการสนับสนุน JMX และ Zabbix (Launcher, Service Graph, JMX, Triggers)
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 - Dynamic Bytecode Generator สำหรับคลาสและวิธีการที่ด้านบนของ Library ASM ObjectWeb บทคัดย่อความซับซ้อนของการจัดการ 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 - serializers ที่รวดเร็วและประหยัดพื้นที่สร้างขึ้นด้วยวิศวกรรมไบต์ แนะนำวิธีการที่ปราศจากสคีมาเพื่อประสิทธิภาพที่ดีที่สุด (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 ที่หลากหลายสำหรับชั้นเรียนแบบคงที่ซึ่งเป็นไปไม่ได้เป็นอย่างอื่น: การกำจัดรหัสตายการ inlining ของวิธีการและค่าคงที่คงที่ (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 - Asynchronous Abstraction เหนือระบบไฟล์สำหรับการสร้างที่เก็บไฟล์ในท้องถิ่นหรือระยะไกลที่มีประสิทธิภาพปรับขนาดได้ซึ่งรองรับความซ้ำซ้อนของข้อมูลการปรับสมดุลและการปรับเปลี่ยน (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- โปรโตคอล Binary-Server Binary-Performance ช่วยให้การสร้างแอพพลิเคชั่น microservice แบบกระจายการกระจายและความผิดพลาด (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 และไลบรารีที่ใช้งานทั้งหมดสามารถพบได้ในโมดูล examples
หมายเหตุการเปิดตัวสำหรับ ActiveJ สามารถพบได้ที่นี่