diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index c90520e75..0993429b9 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -42,6 +42,7 @@ module org.redkale { exports org.redkale.util; exports org.redkale.watch; + uses org.redkale.util.YmlProvider; uses org.redkale.props.spi.PropertiesAgentProvider; uses org.redkale.cached.spi.CachedManagerProvider; uses org.redkale.cluster.spi.ClusterAgentProvider; diff --git a/src/main/java/org/redkale/boot/AppConfig.java b/src/main/java/org/redkale/boot/AppConfig.java index a182fb17b..84ed0b8e6 100644 --- a/src/main/java/org/redkale/boot/AppConfig.java +++ b/src/main/java/org/redkale/boot/AppConfig.java @@ -357,12 +357,19 @@ class AppConfig { String confDir = System.getProperty(RESNAME_APP_CONF_DIR, "conf"); URI appConfFile; boolean fromCache = false; + boolean yml = false; if (confDir.contains("://")) { // jar内部资源 appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.xml"); try { appConfFile.toURL().openStream().close(); - } catch (IOException e) { // 没有application.xml就尝试读application.properties - appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.properties"); + } catch (IOException e) { // 没有application.xml就尝试读application.yml + appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.yml"); + try { + appConfFile.toURL().openStream().close(); + yml = true; + } catch (IOException e2) { // 没有application.xml就尝试读application.properties + appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.properties"); + } } } else if (confDir.charAt(0) == '/' || confDir.indexOf(':') > 0) { // 绝对路径 File f = new File(confDir, "application.xml"); @@ -370,22 +377,36 @@ class AppConfig { appConfFile = f.toURI(); confDir = f.getParentFile().getCanonicalPath(); } else { - f = new File(confDir, "application.properties"); + f = new File(confDir, "application.yml"); if (f.isFile() && f.canRead()) { appConfFile = f.toURI(); confDir = f.getParentFile().getCanonicalPath(); + yml = true; } else { - appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir - try { - appConfFile.toURL().openStream().close(); - } catch (IOException e) { // 没有application.xml就尝试读application.properties - appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties"); + f = new File(confDir, "application.properties"); + if (f.isFile() && f.canRead()) { + appConfFile = f.toURI(); + confDir = f.getParentFile().getCanonicalPath(); + } else { + appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir + try { + appConfFile.toURL().openStream().close(); + } catch (IOException e) { // 没有application.xml就尝试读application.yml + appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.yml"); + try { + appConfFile.toURL().openStream().close(); + yml = true; + } catch (IOException e2) { // 没有application.xml就尝试读application.properties + appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties"); + } + } + confDir = appConfFile + .toString() + .replace("/application.xml", "") + .replace("/application.yml", "") + .replace("/application.properties", ""); + fromCache = true; } - confDir = appConfFile - .toString() - .replace("/application.xml", "") - .replace("/application.properties", ""); - fromCache = true; } } } else { // 相对路径 @@ -394,29 +415,45 @@ class AppConfig { appConfFile = f.toURI(); confDir = f.getParentFile().getCanonicalPath(); } else { - f = new File(new File(home, confDir), "application.properties"); + f = new File(new File(home, confDir), "application.yml"); if (f.isFile() && f.canRead()) { appConfFile = f.toURI(); confDir = f.getParentFile().getCanonicalPath(); + yml = true; } else { - appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir - try { - appConfFile.toURL().openStream().close(); - } catch (IOException e) { // 没有application.xml就尝试读application.properties - appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties"); + f = new File(new File(home, confDir), "application.properties"); + if (f.isFile() && f.canRead()) { + appConfFile = f.toURI(); + confDir = f.getParentFile().getCanonicalPath(); + } else { + appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir + try { + appConfFile.toURL().openStream().close(); + } catch (IOException e) { // 没有application.xml就尝试读application.yml + appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.yml"); + try { + appConfFile.toURL().openStream().close(); + yml = true; + } catch (IOException e2) { // 没有application.xml就尝试读application.properties + appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties"); + } + } + confDir = appConfFile + .toString() + .replace("/application.xml", "") + .replace("/application.yml", "") + .replace("/application.properties", ""); + fromCache = true; } - confDir = appConfFile - .toString() - .replace("/application.xml", "") - .replace("/application.properties", ""); - fromCache = true; } } } System.setProperty(RESNAME_APP_CONF_DIR, confDir); String text = Utility.readThenClose(appConfFile.toURL().openStream()); AnyValue conf; - if (text.trim().startsWith("<")) { + if (yml) { + conf = AnyValue.loadFromYml(text).getAnyValue("redkale"); + } else if (text.trim().startsWith("<")) { conf = AnyValue.loadFromXml(text, (k, v) -> v.replace("${APP_HOME}", home)) .getAnyValue("application"); } else { @@ -425,7 +462,6 @@ class AppConfig { if (fromCache) { ((AnyValueWriter) conf).addValue("[config-from-cache]", "true"); } - return conf; } diff --git a/src/main/java/org/redkale/util/AnyValue.java b/src/main/java/org/redkale/util/AnyValue.java index 4b6de6561..82f1c7c1c 100644 --- a/src/main/java/org/redkale/util/AnyValue.java +++ b/src/main/java/org/redkale/util/AnyValue.java @@ -5,14 +5,13 @@ */ package org.redkale.util; -import static org.redkale.util.Utility.isEmpty; - import java.io.*; import java.nio.charset.*; import java.util.*; import java.util.function.*; import org.redkale.annotation.ConstructorParameters; import org.redkale.convert.ConvertColumn; +import static org.redkale.util.Utility.isEmpty; /** * 该类提供类似JSONObject的数据结构,主要用于读取xml配置文件和http-header存储 @@ -222,6 +221,17 @@ public abstract class AnyValue { return new AnyValueWriter(); } + /** + * yml内容流转换成AnyValue对象 + * + * + * @param text 文本内容 + * @return AnyValue + */ + public static AnyValue loadFromYml(String text) { + return new YmlReader(text).read(); + } + /** * Properties内容转换成AnyValue对象, 层级采用key的.分隔
* key中包含[xx]且xx不是数字且不是位于最后的视为name,会在对应的节点对象中加入name属性 diff --git a/src/main/java/org/redkale/util/YmlProvider.java b/src/main/java/org/redkale/util/YmlProvider.java new file mode 100644 index 000000000..1154a871e --- /dev/null +++ b/src/main/java/org/redkale/util/YmlProvider.java @@ -0,0 +1,27 @@ +/* + +*/ + +package org.redkale.util; + +/** + * 读取yml的解析器 + * + *

详情见: https://redkale.org + * + * @since 2.8.0 + * @author zhangjx + */ +public interface YmlProvider { + + public static final YmlProvider NIL = c -> { + throw new UnsupportedOperationException("Not supported yet."); + }; + + /** + * 将yml内容转换成AnyValue + * @param content yml内容 + * @return AnyValue + */ + public AnyValue read(String content); +} diff --git a/src/main/java/org/redkale/util/YmlReader.java b/src/main/java/org/redkale/util/YmlReader.java new file mode 100644 index 000000000..e1d141b3e --- /dev/null +++ b/src/main/java/org/redkale/util/YmlReader.java @@ -0,0 +1,67 @@ +/* + +*/ + +package org.redkale.util; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.ServiceLoader; +import org.redkale.annotation.Nonnull; + +/** + * 简单的yml读取器 + * TODO 待实现 + * + *

详情见: https://redkale.org + * + * @since 2.8.0 + * @author zhangjx + */ +public class YmlReader { + + private static YmlProvider currentProvider; + + private final String text; + + public YmlReader(String text) { + this.text = Objects.requireNonNull(text); + } + + public AnyValue read() { + YmlProvider provider = loadProvider(); + if (provider == YmlProvider.NIL) { + throw new UnsupportedOperationException("Not supported yml."); + } + return provider.read(text); + } + + /** + * 加载解析器的实现对象 + * + * @return YmlProvider + */ + private static @Nonnull YmlProvider loadProvider() { + if (currentProvider == null) { + Iterator it = ServiceLoader.load(YmlProvider.class).iterator(); + RedkaleClassLoader.putServiceLoader(YmlProvider.class); + List providers = new ArrayList<>(); + while (it.hasNext()) { + YmlProvider provider = it.next(); + if (provider != null) { + RedkaleClassLoader.putReflectionPublicConstructors( + provider.getClass(), provider.getClass().getName()); + providers.add(provider); + } + } + for (YmlProvider provider : Utility.sortPriority(providers)) { + currentProvider = provider; + return provider; + } + currentProvider = YmlProvider.NIL; + } + return currentProvider; + } +} diff --git a/src/test/java/org/redkale/test/mq/MessagedInstanceTest.java b/src/test/java/org/redkale/test/mq/MessagedInstanceTest.java index 11765ff96..4d7b7acfe 100644 --- a/src/test/java/org/redkale/test/mq/MessagedInstanceTest.java +++ b/src/test/java/org/redkale/test/mq/MessagedInstanceTest.java @@ -35,7 +35,7 @@ public class MessagedInstanceTest { private static Application application; private static MessageModuleEngine engine; - + private static ResourceFactory resourceFactory; public static void main(String[] args) throws Throwable { @@ -76,7 +76,7 @@ public class MessagedInstanceTest { @Test public void run2() throws Exception { TestMessageFacade facade = new TestMessageFacade(); - engine.onServicePostInit(null, facade); + engine.onServicePostInit(null, facade); } public static MessageAgent createMessageAgent(Application application, String name) throws Exception {