cn.jiangzeyin.common.ApplicationBuilder Maven / Gradle / Ivy
package cn.jiangzeyin.common;
import cn.hutool.core.util.ClassUtil;
import cn.jiangzeyin.CommonPropertiesFinal;
import cn.jiangzeyin.common.interceptor.BaseInterceptor;
import cn.jiangzeyin.common.spring.event.ApplicationEventClient;
import cn.jiangzeyin.common.spring.event.ApplicationEventLoad;
import cn.jiangzeyin.common.validator.ParameterInterceptor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.env.Environment;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.util.StringUtils;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import java.lang.reflect.*;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* Boot 启动控制
*
* @author jiangzeyin
* @date 2018/4/13
*/
public class ApplicationBuilder extends SpringApplicationBuilder {
/**
* 程序全局控制对象
*/
private volatile static ApplicationBuilder applicationBuilder;
/**
* 程序主类
*/
private Class applicationClass;
private SpringApplication application;
/**
* 程序配置变量
*/
private Environment environment;
/**
* 程序监听事件
*/
private Set applicationEventClients;
/**
* 程序加载完成
*/
private Set applicationEventLoads;
/**
*
*/
private Set> interceptorClass;
/**
*
*/
private Set> httpMessageConverters;
/**
*
*/
private Set> handlerMethodArgumentResolvers;
/**
* 系统预置参数 ,方便多模块间调用
*/
private static final ConcurrentHashMap PRESET_PARAMETER = new ConcurrentHashMap<>();
/**
* 添加预置参数
*
* @param key 参数的名称
* @param value 值
*/
public static void put(String key, Object value) {
PRESET_PARAMETER.put(key, value);
}
/**
* 根据参数名 获取值
*
* @param key 参数名
* @return Object
*/
public static Object get(String key) {
return PRESET_PARAMETER.get(key);
}
/**
* 创建启动对象
*
* @param sources sources
* @return Builder
* @throws NoSuchFieldException e
* @throws IllegalAccessException e
*/
public static ApplicationBuilder createBuilder(Object... sources) throws Exception {
return new ApplicationBuilder(sources);
}
protected ApplicationBuilder(Object... sources) throws Exception {
super(sources);
this.application = application();
if (applicationBuilder != null) {
if (!isRestart()) {
throw new IllegalArgumentException("duplicate create");
}
}
this.applicationClass = this.application.getMainApplicationClass();
// 重写banner
banner((environment, sourceClass, out) -> {
// 最早获取配置信息
ApplicationBuilder.this.environment = environment;
String msg = environment.getProperty(CommonPropertiesFinal.BANNER_MSG, "boot Application starting");
out.println(msg);
});
EnableCommonBoot enableCommonBoot = (EnableCommonBoot) this.applicationClass.getAnnotation(EnableCommonBoot.class);
if (enableCommonBoot == null) {
addLoadPage("cn.jiangzeyin");
} else {
if (enableCommonBoot.parameterValidator()) {
addInterceptor(ParameterInterceptor.class);
}
}
loadProperties("cn.jiangzeyin");
ApplicationBuilder.applicationBuilder = this;
}
public static ApplicationBuilder getInstance() {
if (applicationBuilder == null) {
throw new RuntimeException("Application not start");
}
return applicationBuilder;
}
public Environment getEnvironment() {
if (environment == null) {
throw new RuntimeException("Application not start");
}
return environment;
}
public Set getApplicationEventClients() {
return applicationEventClients;
}
public Set getApplicationEventLoads() {
return applicationEventLoads;
}
public Set> getInterceptorClass() {
return interceptorClass;
}
public Set> getHttpMessageConverters() {
return httpMessageConverters;
}
/**
* 添加响应转换器
*
* @param httpMessageConverter converter
* @return this
*/
public ApplicationBuilder addHttpMessageConverter(HttpMessageConverter> httpMessageConverter) {
Objects.requireNonNull(httpMessageConverter);
if (httpMessageConverters == null) {
this.httpMessageConverters = new HashSet<>();
}
this.httpMessageConverters.add(httpMessageConverter);
return this;
}
/**
* 添加默认拦截器
*
* @param cls cls
* @return this
*/
public ApplicationBuilder addInterceptor(Class extends BaseInterceptor> cls) {
Objects.requireNonNull(cls);
if (interceptorClass == null) {
this.interceptorClass = new HashSet<>();
}
this.interceptorClass.add(cls);
return this;
}
/**
* 添加容器启动监听
*
* @param applicationEventLoad 监听接口
* @return this
*/
public ApplicationBuilder addApplicationEventLoad(ApplicationEventLoad applicationEventLoad) {
Objects.requireNonNull(applicationEventLoad);
if (applicationEventLoads == null) {
this.applicationEventLoads = new HashSet<>();
}
this.applicationEventLoads.add(applicationEventLoad);
return this;
}
/**
* 添加程序事件监听
*
* @param applicationEventClient 监听接口回调
* @return this
*/
public ApplicationBuilder addApplicationEventClient(ApplicationEventClient applicationEventClient) {
Objects.requireNonNull(applicationEventClient);
if (applicationEventClients == null) {
applicationEventClients = new HashSet<>();
}
this.applicationEventClients.add(applicationEventClient);
return this;
}
/**
* 添加参数解析器
*
* @param cls cls
* @return this
*/
public ApplicationBuilder addHandlerMethodArgumentResolver(Class extends HandlerMethodArgumentResolver> cls) {
Objects.requireNonNull(cls);
if (handlerMethodArgumentResolvers == null) {
handlerMethodArgumentResolvers = new HashSet<>();
}
this.handlerMethodArgumentResolvers.add(cls);
return this;
}
public Set> getHandlerMethodArgumentResolvers() {
return handlerMethodArgumentResolvers;
}
/**
* 给程序添加默认包
*
* @param packageName 包名
* @return this
* @throws NoSuchFieldException e
* @throws IllegalAccessException e
*/
@SuppressWarnings("unchecked")
public ApplicationBuilder addLoadPage(String packageName) throws NoSuchFieldException, IllegalAccessException {
if (StringUtils.isEmpty(packageName)) {
throw new IllegalArgumentException("packageName");
}
Object proxy;
String fliedName;
ComponentScan componentScan = (ComponentScan) applicationClass.getAnnotation(ComponentScan.class);
if (componentScan == null) {
SpringBootApplication springBootApplication = (SpringBootApplication) applicationClass.getAnnotation(SpringBootApplication.class);
if (springBootApplication == null) {
throw new IllegalArgumentException("please add " + SpringBootApplication.class);
} else {
proxy = springBootApplication;
fliedName = "scanBasePackages";
}
} else {
proxy = componentScan;
fliedName = "value";
}
InvocationHandler invocationHandler = Proxy.getInvocationHandler(proxy);
Field value = invocationHandler.getClass().getDeclaredField("memberValues");
value.setAccessible(true);
Map memberValues = (Map) value.get(invocationHandler);
String[] values = (String[]) memberValues.get(fliedName);
String[] newValues = new String[]{packageName};
newValues = StringUtils.mergeStringArrays(values, newValues);
memberValues.put(fliedName, newValues);
return this;
}
/**
* 判断是否已热部署
*
* @return true 热部署
*/
public static boolean isRestart() {
String name = Thread.currentThread().getName();
return "restartedMain".equalsIgnoreCase(name);
}
private final HashSet cacheLoadProperties = new HashSet<>();
/**
* 加载配置
*
* @param packageName 指定包名
* @throws Exception e
*/
@SuppressWarnings("unchecked")
public ApplicationBuilder loadProperties(String packageName) throws Exception {
Set> list = ClassUtil.scanPackageByAnnotation(packageName, AutoPropertiesClass.class);
for (Class cls : list) {
if (cacheLoadProperties.contains(cls)) {
continue;
}
Method[] methods = cls.getDeclaredMethods();
if (methods != null) {
for (Method method : methods) {
AutoPropertiesMethod autoPropertiesMethod = method.getAnnotation(AutoPropertiesMethod.class);
if (autoPropertiesMethod == null) {
continue;
}
method.setAccessible(true);
ParameterizedType parameterizedType = (ParameterizedType) method.getGenericReturnType();
Type type = parameterizedType.getRawType();
Class retCls = (Class) type;
int modifiers = method.getModifiers();
Type[] parameters = method.getParameterTypes();
if (parameters.length <= 0 && Map.class == retCls && Modifier.isStatic(modifiers) && Modifier.isPrivate(modifiers)) {
Map map = (Map) method.invoke(null);
if (map != null) {
properties(map);
}
} else {
throw new IllegalArgumentException(cls + " " + method + " " + PreLoadMethod.class + " must use empty parameters static Map private");
}
}
}
cacheLoadProperties.add(cls);
}
return this;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy