177 lines
8.3 KiB
Java

package cn.langpy.kotime.config;
import cn.langpy.kotime.annotation.KoListener;
import cn.langpy.kotime.handler.RunTimeHandler;
import cn.langpy.kotime.handler.InvokedHandler;
import cn.langpy.kotime.service.GraphService;
import cn.langpy.kotime.service.InvokedQueue;
import cn.langpy.kotime.util.Context;
import cn.langpy.kotime.util.DataBaseException;
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Map;
import java.util.logging.Logger;
import java.util.stream.Collectors;
/**
* zhangchang
*/
@ComponentScan("cn.langpy.kotime")
@Configuration
public class LoadConfig {
private static Logger log = Logger.getLogger(LoadConfig.class.toString());
@Value("${koTime.enable:true}")
private Boolean kotimeEnable;
@Value("${koTime.log.language:chinese}")
private String logLanguage;
@Value("${koTime.log.enable:false}")
private Boolean logEnable;
@Value("${koTime.time.threshold:800.0}")
private Double timeThreshold;
@Value("${koTime.pointcut:execution(* cn.langpy.kotime.controller.KoTimeController.*(..))}")
private String pointcut;
@Value("${koTime.exception.enable:false}")
private Boolean exceptionEnable;
@Value("${koTime.saver:memory}")
private String saveSaver;
@Value("${koTime.thread-num:2}")
private Integer threadNum;
@Value("${server.port:8080}")
private Integer serverPort;
@Value("${server.servlet.context-path:}")
private String serverContext;
@Resource
private DefaultConfig defaultConfig;
@Resource
private ApplicationContext applicationContext;
@PostConstruct
public void initConfig() {
DefaultConfig config = new DefaultConfig();
config.setLogEnable(defaultConfig.getLogEnable() == null ? logEnable : defaultConfig.getLogEnable());
config.setLogLanguage(defaultConfig.getLogLanguage() == null ? logLanguage : defaultConfig.getLogLanguage());
config.setThreshold(defaultConfig.getThreshold() == null ? timeThreshold : defaultConfig.getThreshold());
config.setExceptionEnable(defaultConfig.getExceptionEnable() == null ? exceptionEnable : defaultConfig.getExceptionEnable());
config.setSaver(defaultConfig.getSaver() == null ? saveSaver : defaultConfig.getSaver());
config.setEnable(defaultConfig.getEnable() == null ? kotimeEnable : defaultConfig.getEnable());
config.setContextPath(defaultConfig.getContextPath());
config.setLanguage(defaultConfig.getLanguage() == null ? "chinese" : defaultConfig.getLanguage());
config.setThreadNum(defaultConfig.getThreadNum() == null ? 2 : defaultConfig.getThreadNum());
config.setAuthEnable(defaultConfig.getAuthEnable() == null ? false : defaultConfig.getAuthEnable());
config.setParamAnalyse(defaultConfig.getParamAnalyse() == null ? true : defaultConfig.getParamAnalyse());
configDataSource(config);
configRedisTemplate(config);
Context.setConfig(config);
String[] names = applicationContext.getBeanNamesForType(GraphService.class);
for (String name : names) {
GraphService bean = (GraphService) applicationContext.getBean(name);
if (null != bean) {
Component annotation = bean.getClass().getAnnotation(Component.class);
if (config.getSaver().equals(annotation.value())) {
Context.setSaver(bean);
break;
}
}
}
if (null == Context.getSaver()) {
throw new DataBaseException("error `ko-time.saver=" + config.getSaver() + "`, and you can only choose an option in {memory,database,redis} for `ko-time.saver=`!");
}
log.info("kotime=>loading config");
if (StringUtils.hasText(config.getContextPath())) {
log.info("kotime=>view:" + Context.getConfig().getContextPath() + "/koTime");
} else {
log.info("kotime=>view:http://localhost:" + serverPort + serverContext + "/koTime");
}
initMethodHandlers();
}
public void configDataSource(DefaultConfig config) {
if (!"database".equals(config.getSaver())) {
return;
}
try {
DataSource dataSource = applicationContext.getBean(DataSource.class);
Context.setDataSource(dataSource);
} catch (NoUniqueBeanDefinitionException e) {
if (StringUtils.isEmpty(config.getDataSource())) {
log.warning("kotime=>No unique bean of type 'DataSource' available,you can define it by `ko-time.data-source=xxx`");
} else {
DataSource dataSource = applicationContext.getBean(config.getDataSource(), DataSource.class);
Context.setDataSource(dataSource);
}
} catch (NoSuchBeanDefinitionException e) {
log.warning("kotime=>No qualifying bean of type 'DataSource' available,but you can ignore it if your KoTime saver is `ko-time.saver=memory`");
}
}
public void configRedisTemplate(DefaultConfig config) {
if (!"redis".equals(config.getSaver())) {
return;
}
try {
StringRedisTemplate redisTemplate = applicationContext.getBean(StringRedisTemplate.class);
Context.setStringRedisTemplate(redisTemplate);
} catch (NoUniqueBeanDefinitionException e) {
if (!StringUtils.isEmpty(config.getRedisTemplate())) {
StringRedisTemplate redisTemplate = applicationContext.getBean(config.getRedisTemplate(), StringRedisTemplate.class);
Context.setStringRedisTemplate(redisTemplate);
} else {
Map<String, StringRedisTemplate> beansOfType = applicationContext.getBeansOfType(StringRedisTemplate.class);
log.warning("kotime=>No unique bean of type 'StringRedisTemplate' available,you can define it by `ko-time.redis-template=xxx`,and you can choose a name in "+beansOfType.keySet().stream().collect(Collectors.toList()));
log.warning("kotime=>Now the firsr was be set.");
Context.setStringRedisTemplate(beansOfType.values().stream().collect(Collectors.toList()).get(0));
}
} catch (NoSuchBeanDefinitionException e) {
log.warning("kotime=>No qualifying bean of type 'StringRedisTemplate' available,but you can ignore it if your KoTime saver is `ko-time.saver=memory`");
}
}
public void initMethodHandlers() {
String[] names = applicationContext.getBeanNamesForType(InvokedHandler.class);
for (String name : names) {
InvokedHandler bean = (InvokedHandler) applicationContext.getBean(name);
if (null != bean) {
KoListener annotation = bean.getClass().getAnnotation(KoListener.class);
if (null == annotation) {
continue;
}
log.info("kotime=>loading InvokedHandler:" + bean.getClass().getSimpleName());
Context.addInvokedHandler(bean);
}
}
for (int i = 0; i < Context.getConfig().getThreadNum(); i++) {
new Thread(() -> InvokedQueue.onInveked()).start();
}
}
@Bean
public AspectJExpressionPointcutAdvisor configurabledvisor() {
log.info("kotime=>loading method listener");
AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
String cutRange = defaultConfig.getPointcut() == null ? pointcut : defaultConfig.getPointcut();
cutRange = cutRange + " && !@annotation(cn.langpy.kotime.annotation.KoListener)";
advisor.setExpression(cutRange);
advisor.setAdvice(new RunTimeHandler());
return advisor;
}
}