Skip to content

🔥 Java enterprise application development framework for full scenario: Restrained, Efficient, Open, Ecologicalll!!! 300% higher concurrency 50% memory savings Startup is 10 times faster. Packing 90% smaller; Compatible with java8 ~ java23. (Replaceable spring)

License

Notifications You must be signed in to change notification settings

opensolon/solon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

19f4529 · Jun 8, 2021
Jun 7, 2021
Jun 8, 2021
Jun 7, 2021
Jun 6, 2021
Jun 7, 2021
Jun 7, 2021
Jun 6, 2021
Jun 6, 2021
Jun 7, 2021
Jun 6, 2021
Jun 6, 2021
Jun 6, 2021
Jun 6, 2021
Jun 7, 2021
Dec 23, 2020
Dec 23, 2019
Jun 6, 2021
Jun 6, 2021
Jun 4, 2021
Jun 7, 2021
Mar 7, 2021
Jun 8, 2021

Repository files navigation

Maven Central

QQ交流群:22200020

Solon for java

A plug-in lightweight Java development framework。Faster, smaller, freer!

Support jdk8 +; Core frame 0.1Mb; Combining different plug-ins to meet different needs; Convenient customization; Rapid development of。

  • Restrained, concise and open
  • Unified development experience of HTTP, WebSocket and Socket signals (commonly known as three sources in one)
  • Support annotation and manual two modes, free control as needed
  • Not Servlets, which can be adapted to any underlying communication framework (so: RPC architecture runs at minimum 0.2Mb)
  • Self-built IOC & AOP container, support REST API, MVC, Job, Remoting, MicoService and other development
  • Set Handler + Context and Listener + Message architecture patterns; Emphasis on plug-in extension; Adapt to different application scenarios
  • Plug-ins are extensible and switchable: startup plug-in, extension plug-in, serialization plug-in, data plug-in, session state plug-in, view plug-in (coexist), etc.
  • The use of Spring Boot feels similar to the migration cost is low

Hello world:

//Handler mode:
public class App{
    public static void main(String[] args){
        SolonApp app = Solon.start(App.class,args);
        
        app.get("/",(c)->c.output("Hello world!"));
    }
}

//Controller mode::(mvc or rest-api)
@Controller
public class App{
    public static void main(String[] args){
        Solon.start(App.class,args);
    }
  
    @Get
    @Mapping("/")
    public Object hello(Context c){
        return "Hello world!";  
    }
}

//Remoting mode:(rpc)
@Mapping("/")
@Http
@Socket
@Remoting
public class App implements HelloService{
    public static void main(String[] args){
        Solon.start(App.class,args);
    }

    @Override
    public String hello(){
        return "Hello world!";
    }
}

Main framework and rapid integration development package:

Main frame
component or plugin description
org.noear:solon-parent Framework versioning
org.noear:solon Main frame
org.noear:nami Companion Framework (as a client to Solon Remoting)
Rapid integration of development packages and relationships
component or plugin description
org.noear:solon-lib Rapid development of basic integration packages
org.noear:solon-api solon-lib + http boot;Rapid development of interface applications
org.noear:solon-web solon-api + freemarker + sessionstate;Rapid development of WEB applications
org.noear:solon-beetl-web solon-api + beetl + sessionstate;Rapid development of WEB applications
org.noear:solon-enjoy-web solon-api + enjoy + sessionstate;Rapid development of WEB applications
org.noear:solon-rpc solon-api + nami;Rapid development of remoting applications
org.noear:solon-cloud solon-rpc + consul;Rapid development of microservice applications

Attachment 1: A quick understanding of Solon's materials:

Attachment 2: Examples and articles

Attachment 3: Quick Start Examples

  • Web example(mvc)
<parent>
    <groupId>org.noear</groupId>
    <artifactId>solon-parent</artifactId>
    <version>1.4.12</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.noear</groupId>
        <artifactId>solon-web</artifactId>
    </dependency>
</dependencies>
//Resource path specification (no configuration)
resources/application.properties(or application.yml) #Configuration files for the application
resources/static/ #Is the static file root target
resources/WEB-INF/view/ #The root target of the view file (supports coexistence of multiple views)

//Debug mode:
Add startup parameters:-debug=1
public class App{
    public static void main(String[] args){
        Solon.start(App.class, args);
    }
}

/*
 * mvc controller
 */
@Controller
public class DemoController{
    //for http
    @Mapping("/hallo/{u_u}")
    public ModelAndView hallo(String u_u){
        return new ModelAndView("hallo");
    }
    
    /*
    //for web socket (Need to add: solon.boot.websocket plug-in)
    @Mapping(value="/hallo/{u_u}", method = MethodType.WEBSOCKET)
    public ModelAndView hallo_ws(String u_u){
        return new ModelAndView("hallo");
    }
    */
}
  • Remoting example(rpc)
// - interface : Defines the interface
public interface DemoService{
    void setName(Integer user_id, String name);
}

// - server : Implementing an interface
@Mapping("/demo/*")
@Remoting
public class DemoServiceImp implements DemoService{
    public void setName(int user_id, String name){
        
    }
}

// - client - A simple example
//Injection pattern
//@NamiClient("http://127.0.0.1:8080/demo/") 
//DemoService client;

//Manual build mode
DemoService client = Nami.builder().url("http://127.0.0.1:8080/demo/").create(DemoService.class); 
client.setName(1,'');
  • Get the application configuration
//Manual mode
Solon.cfg().get("app_key"); //=>String
Solon.cfg().getInt("app_id",0); //=>int
Solon.cfg().getProp("xxx.datasource"); //=>Properties

//Injection pattern
@Configuration //or @Controller, or @Component
public class Config{
    @Inject("${app_key}")
    String app_key;

    @Inject("${app_title:Solon}")
    String app_title;
}
  • Transaction and cache control (+ validation)
@Valid
@Controller
public class DemoController{
    @Db
    BaseMapper<UserModel> userService;
    
    @NotZero("user_id")
    @CacheRemove(tags = "user_${user_id}")
    @Tran
    @Mapping("/user/update")
    public void udpUser(int user_id, UserModel user){
        userService.updateById(user);
    }

    @NotZero("user_id")
    @Cache(tags = "user_${user_id}")
    public UserModel getUser(int user_id){
        return userService.selectById(user_id);
    }
}
  • File upload and output
@Controller
public class DemoController{
    @Mapping("/file/upload")
    public void upload(UploadedFile file){
        IoUtil.save(file.content, "/data/file_" + file.name);
    }

    @Mapping("/file/down")
    public void down(Context ctx, String path){
        URL uri = Utils.getResource(path);

        ctx.contentType("json/text");
        ctx.output(uri.openStream());
    }
}
  • Servlet annotations are still supported
@WebFilter("/hello/*")
public class HelloFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletResponse.getWriter().write("Hello,I filtered you out");
    }
}
  • Quartz Timing task
@Quartz(cron7x = "0 0/1 * * * ? *")
public class HelloTask implements Runnable {
    public static void main(String[] args){
        Solon.start(QuartzRun2.class,args);
    }
    
    @Override
    public void run() {
        System.out.println("Hello world");
    }
}
  • External extensions load the JAR
demoApp.jar             #The main program
ext/                    #Extensions directory
ext/ext.markdown.jar    #The MD format supports extension packs
  • Single-linked bidirectional RPC (after the server on the client chain, form a bidirectional RPC)
//server
@Mapping(value = "/demoh/rpc", method = MethodType.SOCKET)
@Remoting
public class HelloRpcServiceImpl implements HelloRpcService {
    public String hello(String name) {
        //Here, you can create an RPC service that connects to the client based on the client session
        NameRpcService rpc = SocketD.create(Context.current(), NameRpcService.class);

        String name2 = rpc.name(name);

        return "name=" + name;
    }
}

//client
HelloRpcService rpc = SocketD.create("tcp://localhost:"+_port, HelloRpcService.class);

String rst = rpc.hello("noear");
  • Solon cloud Configure service usage
@Controller
public class DemoController {
    public static void main(String[] args){
        Solon.start(DemoController.class,args);
    }
    
    //Injection pattern
    @CloudConfig(value = "user.name", autoRefreshed = true)
    String userName;
    
    @Mapping("/")
    public void run() {
        //Manual mode
        userName = CloudClient.config().pull("user.name").value();
    }
}
  • Solon cloud event bus usage
//Event subscription and consumption
@CloudEvent("hello.demo")
public class DemoEvent implements CloudEventHandler {
    @Override
    public boolean handler(Event event) throws Throwable {
        //Return to success
        return true;
    }
}

//Event production
CloudClient.event().publish(new Event("hello.demo", msg));
  • Solon cloud distributed job usage
//Annotation mode - Handler style
@CloudJob("JobHandlerDemo1")
public class JobHandlerDemo1 implements Handler {
    @Override
    public void handle(Context ctx) throws Throwable {
        //任务处理
    }
}

//Manual mode
CloudClient.job().register("JobHandlerDemo3","",c->{
    //任务处理 
});

Attachment 4: Plug-in development instructions

  • Create a new Maven project
  • Create a new java file: /{package name}/XPluginImp.java (implements XPlugin)
  • Create a new properties file: /META-INF/solon/{package.properties}
  • Add configuration: solon.plugin={package name}.XPluginImp

Attachment 5: Start sequence reference

    1. Instantiate solon.global () and load the configuration
    1. Load the extension folder
    1. Scan and sort plug-ins
    1. Run initialize function
    1. Push AppInitEndEvent [event]
    1. Run the plug-in
    1. Push pluginLoadEndEvent [event]
    1. Import Java beans (@import)
    1. Scan and load the Java beans
  • a. Push BeanLoadEndEvent [event]
  • b. Load render printout
  • c. Execute bean plus completion event
  • d. Push PloadendEvent [event]
  • e in the end

Attachment 6: The number of concurrency per machine of HelloWorld 《helloworld_wrk_test》

  • The machine:2017 macbook pro 13, i7, 16g, MacOS 10.15, jdk11
  • Test:wrk -t10 -c200 -d30s --latency "http://127.0.0.1:8080/"
solon 1.1.2 Packet size QPS
solon.boot.jlhttp(bio) 0.1m 4.7万左右
solon.boot.jetty(nio, support servlet api) 1.8m 10.7万左右
solon.boot.undertow(nio, support servlet api) 4.2m 11.3万左右
solon.boot.smarthttp(aio) 0.3m 12.4万左右
spring boot 2.3.3 Packet size QPS
spring-boot-starter-tomcat 16.1m 3.2万左右
spring-boot-starter-jetty 16m 3.7万左右
spring-boot-starter-undertow 16.8m 4.4万左右

About

🔥 Java enterprise application development framework for full scenario: Restrained, Efficient, Open, Ecologicalll!!! 300% higher concurrency 50% memory savings Startup is 10 times faster. Packing 90% smaller; Compatible with java8 ~ java23. (Replaceable spring)

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages