blade-tool/blade-core-launch/src/main/java/org/springblade/core/launch/BladeApplication.java

139 lines
6.2 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springblade.core.launch;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.launch.constant.NacosConstant;
import org.springblade.core.launch.constant.SentinelConstant;
import org.springblade.core.launch.service.LauncherService;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.*;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 项目启动器,搞定环境变量问题
*
* @author Chill
*/
public class BladeApplication {
/**
* Create an application context
* java -jar app.jar --spring.profiles.active=prod --server.port=2333
*
* @param appName application name
* @param source The sources
* @return an application context created from the current state
*/
public static ConfigurableApplicationContext run(String appName, Class source, String... args) {
SpringApplicationBuilder builder = createSpringApplicationBuilder(appName, source, args);
return builder.run(args);
}
public static SpringApplicationBuilder createSpringApplicationBuilder(String appName, Class source, String... args) {
return createSpringApplicationBuilder(null,appName, source, args);
}
/**
* 兼容tomcat等外部容器启动使用此方法时请按照1进行工程改造
* <pre>1-https://sns.bladex.cn/q-6813.html</pre>
* <pre>2-解决https://sns.bladex.cn/q-66.html问题</pre>
* @param builder builder
* @param appName appName
* @param source source
* @param args args
* @return
*/
public static SpringApplicationBuilder createSpringApplicationBuilder(SpringApplicationBuilder builder,String appName, Class source, String... args){
Assert.hasText(appName, "[appName]服务名不能为空");
// 读取环境变量使用spring boot的规则
ConfigurableEnvironment environment = new StandardEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
propertySources.addFirst(new SimpleCommandLinePropertySource(args));
propertySources.addLast(new MapPropertySource(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, environment.getSystemProperties()));
propertySources.addLast(new SystemEnvironmentPropertySource(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, environment.getSystemEnvironment()));
// 获取配置的环境变量
String[] activeProfiles = environment.getActiveProfiles();
// 判断环境:dev、test、prod
List<String> profiles = Arrays.asList(activeProfiles);
// 预设的环境
List<String> presetProfiles = new ArrayList<>(Arrays.asList(AppConstant.DEV_CODE, AppConstant.TEST_CODE, AppConstant.PROD_CODE));
// 交集
presetProfiles.retainAll(profiles);
// 当前使用
List<String> activeProfileList = new ArrayList<>(profiles);
Function<Object[], String> joinFun = StringUtils::arrayToCommaDelimitedString;
if(builder==null){
// 如果builder为空 创建 此操作将启动内嵌web容器 以jar模式启动
builder = new SpringApplicationBuilder(source);
}
String profile;
if (activeProfileList.isEmpty()) {
// 默认dev开发
profile = AppConstant.DEV_CODE;
activeProfileList.add(profile);
builder.profiles(profile);
} else if (activeProfileList.size() == 1) {
profile = activeProfileList.get(0);
} else {
// 同时存在dev、test、prod环境时
throw new RuntimeException("同时存在环境变量:[" + StringUtils.arrayToCommaDelimitedString(activeProfiles) + "]");
}
String startJarPath = BladeApplication.class.getResource("/").getPath().split("!")[0];
String activePros = joinFun.apply(activeProfileList.toArray());
System.out.println(String.format("----启动中,读取到的环境变量:[%s]jar地址:[%s]----", activePros, startJarPath));
Properties props = System.getProperties();
props.setProperty("spring.application.name", appName);
props.setProperty("spring.profiles.active", profile);
props.setProperty("info.version", AppConstant.APPLICATION_VERSION);
props.setProperty("info.desc", appName);
props.setProperty("blade.env", profile);
props.setProperty("blade.name", appName);
props.setProperty("blade.is-local", String.valueOf(isLocalDev()));
props.setProperty("blade.dev-mode", profile.equals(AppConstant.PROD_CODE) ? "false" : "true");
props.setProperty("blade.service.version", AppConstant.APPLICATION_VERSION);
props.setProperty("spring.main.allow-bean-definition-overriding", "true");
props.setProperty("spring.cloud.nacos.config.prefix", NacosConstant.NACOS_CONFIG_PREFIX);
props.setProperty("spring.cloud.nacos.config.file-extension", NacosConstant.NACOS_CONFIG_FORMAT);
props.setProperty("spring.cloud.sentinel.transport.dashboard", SentinelConstant.SENTINEL_ADDR);
props.setProperty("spring.cloud.alibaba.seata.tx-service-group", appName.concat(NacosConstant.NACOS_GROUP_SUFFIX));
// 加载自定义组件
List<LauncherService> launcherList = new ArrayList<>();
ServiceLoader.load(LauncherService.class).forEach(launcherList::add);
SpringApplicationBuilder finalBuilder = builder;
launcherList.stream().sorted(Comparator.comparing(LauncherService::getOrder)).collect(Collectors.toList())
.forEach(launcherService -> launcherService.launcher(finalBuilder, appName, profile));
return finalBuilder;
}
/**
* 判断是否为本地开发环境
*
* @return boolean
*/
public static boolean isLocalDev() {
String osName = System.getProperty("os.name");
return StringUtils.hasText(osName) && !(AppConstant.OS_NAME_LINUX.equals(osName.toUpperCase()));
}
}