ActiveJ는 처음부터 제작 된 최신 Java 플랫폼입니다. 자급 자족 (타사 종속성 없음)으로 단순하고 가벼우 며 경쟁력있는 성능을 제공하도록 설계되었습니다. ActiveJ는 의존성 주입 및 고성능 비동기 I/O (Node.js에서 영감), 애플리케이션 서버 및 빅 데이터 솔루션에 이르기까지 다양한 직교 라이브러리로 구성됩니다.
이 라이브러리는 서로와 관련하여 가능한 한 적은 의존성을 가지고 있으며 함께 또는 별도로 사용할 수 있습니다. ActiveJ에서는 사용자가 전혀 또는 전혀 사용하지 않도록하는 또 다른 프레임 워크가 아닌 ActiveJ는 특정 작업에 대한 라이브러리 구성 요소를 선택하는 측면에서 가능한 한 많은 자유를 제공합니다.
ActiveJ는 여러 모듈로 구성되며 다음 범주로 논리적으로 그룹화 할 수 있습니다.
async.io- 효율적인 이벤트 루프, NIO, 약속, 스트리밍 및 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- 고성능 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"
}부팅 - 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- 바이트 코드 엔지니어링으로 생성 된 빠르고 공간 효율적인 시리얼 라이저. 최상의 성능을위한 스키마 프리 접근법을 소개합니다. (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 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의 릴리스 노트는 여기에서 찾을 수 있습니다