001/** 002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.jboot.app; 017 018import com.jfinal.config.Interceptors; 019import com.jfinal.config.Plugins; 020import com.jfinal.core.JFinal; 021import com.jfinal.plugin.IPlugin; 022import io.jboot.app.config.JbootConfigManager; 023import io.jboot.core.JbootCoreConfig; 024 025import java.lang.reflect.Method; 026import java.text.DecimalFormat; 027import java.util.List; 028import java.util.concurrent.locks.Condition; 029import java.util.concurrent.locks.ReentrantLock; 030 031/** 032 * @author michael yang (fuhai999@gmail.com) 033 * @Date: 2020/3/24 034 */ 035public class JbootSimpleApplication { 036 037 private static final ReentrantLock LOCK = new ReentrantLock(); 038 private static final Condition STOP = LOCK.newCondition(); 039 040 public static void main(String[] args) { 041 run(args); 042 } 043 044 public static void setBootArg(String key, Object value) { 045 JbootConfigManager.setBootArg(key, value); 046 } 047 048 public static void run(String[] args) { 049 050 long startTimeMillis = System.currentTimeMillis(); 051 052 JbootApplicationConfig appConfig = ApplicationUtil.getAppConfig(args); 053 ApplicationUtil.printBannerInfo(appConfig); 054 ApplicationUtil.printApplicationInfo(appConfig); 055 ApplicationUtil.printClassPath(); 056 057 JbootCoreConfig coreConfig = new JbootCoreConfig(); 058 new SimpleServer(coreConfig, startTimeMillis).start(); 059 } 060 061 062 static class SimpleServer extends Thread { 063 064 private final JbootCoreConfig coreConfig; 065 private final long startTimeMillis; 066 private final Plugins plugins = new Plugins(); 067 private final Interceptors interceptors = new Interceptors(); 068 069 public SimpleServer(JbootCoreConfig coreConfig, long startTimeMillis) { 070 this.coreConfig = coreConfig; 071 this.startTimeMillis = startTimeMillis; 072 073 doInitJFinalPathKit(); 074 doInitCoreConfig(); 075 } 076 077 078 private void doInitJFinalPathKit() { 079 try { 080 Class<?> c = JbootSimpleApplication.class.getClassLoader().loadClass("com.jfinal.kit.PathKit"); 081 Method setWebRootPath = c.getMethod("setWebRootPath", String.class); 082 String webRootPath = PathKitExt.getWebRootPath(); 083 setWebRootPath.invoke(null, webRootPath); 084 085 // ------- 086 Method setRootClassPath = c.getMethod("setRootClassPath", String.class); 087 String rootClassPath = PathKitExt.getRootClassPath(); 088 setRootClassPath.invoke(null, rootClassPath); 089 } catch (Exception ex) { 090 throw new RuntimeException(ex); 091 } 092 } 093 094 private void doInitCoreConfig() { 095 096 //constants 097 coreConfig.configConstant(JFinal.me().getConstants()); 098 099 //aop interceptors 100 coreConfig.configInterceptor(interceptors); 101 102 //plugins 103 coreConfig.configPlugin(plugins); 104 startPlugins(); 105 106 //on start 107 coreConfig.onStart(); 108 } 109 110 private void startPlugins() { 111 List<IPlugin> pluginList = plugins.getPluginList(); 112 if (pluginList == null) { 113 return; 114 } 115 116 for (IPlugin plugin : pluginList) { 117 try { 118 if (plugin.start() == false) { 119 String message = "Plugin start error: " + plugin.getClass().getName(); 120 throw new RuntimeException(message); 121 } 122 } catch (Exception e) { 123 String message = "Plugin start error: " + plugin.getClass().getName() + ". \n" + e.getMessage(); 124 throw new RuntimeException(message, e); 125 } 126 } 127 } 128 129 @Override 130 public void run() { 131 String seconds = new DecimalFormat("#.#").format((System.currentTimeMillis() - startTimeMillis) / 1000F); 132 System.out.println("JbootApplication has started in " + seconds + " seconds. Welcome To The Jboot World (^_^)\n\n"); 133 134 initShutdownHook(); 135 startAwait(); 136 } 137 138 139 private void initShutdownHook() { 140 Runtime.getRuntime().addShutdownHook(new Thread(() -> { 141 System.out.println("\nJbootApplication shutdown, please wait ...... "); 142 try { 143 coreConfig.onStop(); 144 } catch (Exception e) { 145 System.out.println("JbootApplication shutdown exception: " + e.toString()); 146 } 147 System.out.println("JbootApplication has exited, all services stopped."); 148 try { 149 LOCK.lock(); 150 STOP.signal(); 151 } finally { 152 LOCK.unlock(); 153 } 154 }, "jboot-simple-application-hook")); 155 } 156 157 158 private void startAwait() { 159 try { 160 LOCK.lock(); 161 STOP.await(); 162 } catch (InterruptedException e) { 163 System.out.println("JbootApplication has stopped, interrupted by other thread!"); 164 } finally { 165 LOCK.unlock(); 166 } 167 } 168 169 170 } 171 172}