feat(Java_SpringExample): 增加Properties文件字段读取两种方式(propertiesScan),PostConstruct的使用、BeanPostProcessor在Bean初始化前后进行处理(init)、统一异常处理的两种方式(exceptionHandler)、统一出参报文处理(response)、新增上下文刷新判断处理类(refreshEvent)、添加HttpSession监听器(listener)

This commit is contained in:
huangzj
2020-06-01 18:06:44 +08:00
parent e65411be30
commit c7be721cc2
19 changed files with 887 additions and 7 deletions
+3
View File
@@ -4,3 +4,6 @@
2020/5/22 : 创建工程(代码有问题,先提交)
2020/5/26 : AspectJ代码提交,代码报错未解决
2020/5/29 : 增加Properties文件字段读取两种方式(propertiesScan),PostConstruct的使用、BeanPostProcessor在Bean初始化前后进行处理(init)、统一异常处理的两种方式(exceptionHandler)、统一出参报文处理(response)
新增上下文刷新判断处理类(refreshEvent)、添加HttpSession监听器(listener
+3 -3
View File
@@ -76,8 +76,8 @@ public class MvcComponentLoader extends WebMvcConfigurerAdapter {
* @return
*/
// @Bean
// public MyExceptionHandler getExceptionHandler() {
// return new MyExceptionHandler();
// public ExceptionResolver getExceptionHandler() {
// return new ExceptionResolver();
// }
/**
@@ -86,7 +86,7 @@ public class MvcComponentLoader extends WebMvcConfigurerAdapter {
*/
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
// exceptionResolvers.add(new MyExceptionHandler());
// exceptionResolvers.add(new ExceptionResolver());
// ...
}
+5 -3
View File
@@ -1,5 +1,6 @@
package config;
import config.refreshEvent.ContextRefreshEvent;
import filter.FilterDelegator;
import filter.WelcomeHandlingFilter;
import org.springframework.util.StringUtils;
@@ -30,11 +31,12 @@ public class WebInitializer extends AbstractAnnotationConfigDispatcherServletIni
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
/**配置和监听器*/
// 配置和监听器
registerServletFilters(servletContext);
registerListeners(servletContext);
// QuartzListener quartzListener = new QuartzListener();
// servletContext.addListener(quartzListener.getClass());
//刷新事件需要作为监听器在这边配置
ContextRefreshEvent refreshEvent = new ContextRefreshEvent();
servletContext.addListener(refreshEvent.getClass());
}
@@ -0,0 +1,52 @@
package config.exceptionHandler;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
@ControllerAdvice
public class AnnoExceptionHandler {
/**
* @a
* @param exception
* @return
*/
@ExceptionHandler(CustomGenericException.class)//可以直接写@ExceptionHandler,不指明异常类,会自动映射
public ModelAndView customGenericExceptionHnadler(CustomGenericException exception){ //还可以声明接收其他任意参数
ModelAndView modelAndView = new ModelAndView("generic_error");
modelAndView.addObject("errCode",exception.getErrCode());
modelAndView.addObject("errMsg",exception.getErrMsg());
return modelAndView;
}
@ExceptionHandler(Exception.class)//可以直接写@EceptionHandlerIOExeption继承于Exception
public ModelAndView allExceptionHandler(Exception exception){
ModelAndView modelAndView = new ModelAndView("generic_error");
modelAndView.addObject("errMsg", "this is Exception.class");
return modelAndView;
}
public class CustomGenericException extends RuntimeException{
private static final long serialVersionUID = 1L;
private String errCode;
private String errMsg;
public String getErrCode() {
return errCode;
}
public String getErrMsg() {
return errMsg;
}
public CustomGenericException(String errCode, String errMsg) {
this.errCode = errCode;
this.errMsg = errMsg;
}
}
}
@@ -0,0 +1,56 @@
package config.exceptionHandler;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author 志军
* 继承spring的问题处理类, spring有默认的异常处理体系,默认的异常处理体系是先进行处理的。
* 这里继承Order接口可以把我们的处理器作为位置0的处理器。但是默认的异常处理器的位置也是0,所以我们无法控制他们谁先处理
*
* 可以参考MvcComponentLoader的描述
*
* 通过继承接口进行处理是第一种方式
*/
@Order(value = 0)
public class ExceptionResolver implements HandlerExceptionResolver {
/**
* 厉害了。这边也可测试一下如果是不给这个异常放在第一位的话,会出现什么情况,
* 其他的异常处理体系是不是会把异常进行处理
*/
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.printf("发现了异常,进入%s类", ExceptionResolver.class.getName());
System.out.printf("错误信息:%s", ex.getMessage());
//这里是匹配错误类型,把错误信息加上的地方 - 你可能会匹配很多的错误,这里的做法应该是对错误进行分类。
ExceptionResponse exceptionResponse = null;
if (ex instanceof MethodArgumentNotValidException) {
MethodArgumentNotValidException methodArgumentNotValidException = (MethodArgumentNotValidException) ex;
//这里面包含了错误的信息
System.out.println(methodArgumentNotValidException.toString());
exceptionResponse = new ExceptionResponse("500","报错");
}
//最后就是异常处理返回
MappingJackson2JsonView view = new MappingJackson2JsonView();
view.setExtractValueFromSingleKeyModel(true);
return new ModelAndView(view, "response",exceptionResponse);
}
}
class ExceptionResponse{
private String code;
private String message;
ExceptionResponse(String code, String message) {
this.code = code;
this.message = message;
}
}
+22
View File
@@ -0,0 +1,22 @@
package config.init;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* @author 志军
* 测试一下<code>@PostConstruct</code>注解
*/
@Component
public class InitPost {
/**
* 该注解相当于servlet的init方法,且只会执行一次
* 不知道这个的执行顺序,后面可以再了解一下
*/
@PostConstruct
public void initPost(){
System.out.println("我被初始化了");
}
}
@@ -0,0 +1,46 @@
/*
* @(#) MyBeanPostProcess
* 版权声明 黄志军, 版权所有 违者必究
*
* <br> Copyright: Copyright (c) 2018
* <br> Company:黄志军
* <br> @author selfImpr
* <br> 2018-05-28 22:19:40
* <br> @description
*
*
*/
package config.init;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* @author 志军
* 自定义Bean初始化前后处理的方法
* 这边Spring使用的也是模板模式
*/
@Component
public class SelfBeanPostProcess implements BeanPostProcessor {
/**
* 在Bean初始化之前进行处理
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("beanName-----------" + beanName);
return bean;
}
/**
* 在Bean初始化之后进行处理
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
}
@@ -0,0 +1,42 @@
package config.propertiesScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
/**
* @author selfimpr
* @description 通过该配置来实现对properties的属性进行读取
* @date 2017/11/11 21:25
*
* <code>@PropertySource</code>注解 解决中文乱码问题 好像还是需要设置IDEA的编码
* //参考地址:http://blog.csdn.net/j3oker/article/details/53839210
*/
@Configuration
@PropertySource(value = "classpath:appilcation.properties",encoding = "UTF-8")
public class PropertiesScan {
@Value("${area_id}")
public String isBorder;
@Value("${local_request_id}")
public String borderColor;
public String getIsBorder() {
return isBorder;
}
public String getBorderColor() {
return borderColor;
}
/**
* 要想使用@Value 用${}占位符注入属性,这个bean是必须的,这个就是占位bean,另一种方式是不用value直接用Envirment变量直接getProperty('key')
*/
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
@@ -0,0 +1,96 @@
package config.propertiesScan;
import util.FileUtil;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* 通过这个类来扫描获取所有的properties下面的文件
* 这个监听器在Servlet上下文初始化过程中进行处理
* @author 志军
*/
@WebListener
public class PropertiesScanByListener implements ServletContextListener {
private Map<String, String> map = new HashMap<>();
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
String resourcesPath = servletContext.getRealPath("/") + "WEB-INF\\classes\\cache";
traceFilesAndGetProperties(resourcesPath);
servletContext.setAttribute("properties", map);
System.out.println(map);
}
private void traceFilesAndGetProperties(String path) {
if (FileUtil.isDir(path)) {
File[] files = new File(path).listFiles();
if (files == null || files.length == 0) {
System.out.println("文件夹是空的!");
} else {
for (File file2 : files) {
if (file2.isDirectory()) {
System.out.println("文件夹:" + file2.getAbsolutePath());
traceFilesAndGetProperties(file2.getAbsolutePath());
} else {
//是否是配置文件
if (file2.getAbsolutePath().contains(".properties")) {
getProperties(file2.getAbsolutePath());
}
}
}
}
return;
}
if (FileUtil.isFile(path)){
if (new File(path).getAbsolutePath().contains(".properties")) {
getProperties(new File(path).getAbsolutePath());
}
return;
}
throw new RuntimeException("文件不存在");
}
private void getProperties(String filePath) {
Properties properties = new Properties();
InputStream in = null;
try {
in = new FileInputStream(filePath);
properties.load(in);
for (Object o : properties.keySet()) {
String key = (String) o;
String value = properties.getProperty(key);
map.put(key, value);
}
} catch (IOException e) {
throw new RuntimeException(e );
} finally {
try {
if (null != in) {
in.close();
}
} catch (IOException e) {
System.out.println("文件流关闭失败:"+e.toString());
}
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
@@ -0,0 +1,57 @@
package config.refreshEvent;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
@PropertySource("classpath:/app.properties")
public class ContextRefreshEvent implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private Environment environment;
/**
* 程序启动,上下文刷新或者初始化的时候会调用该方法
* Event raised when an {@code ApplicationContext} gets initialized or refreshed.
* 这边是选择在 onStartup方法上去配置这个监听器,但是也可以直接用@WebListener去注册这个监听器
*/
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
//因为Spring有两个上下文容器,所以这边加上一个判断,让程序运营在住容器的时候就进行定时任务的执行.
if (event.getApplicationContext().getParent() == null) {
try {
//"0 0 3/1 3 * ? * ";
String timerTime = environment.getProperty("cron");
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("dummyTriggerName", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule(timerTime))
.build();
JobDetail job = JobBuilder.newJob(HelloJob.class)
.withIdentity("dummyJobName", "group1").build();
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
throw new RuntimeException(e);
}
}
}
class HelloJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.print("hello quartz ");
}
}
}
@@ -0,0 +1,81 @@
/*
* @(#) ShareResponseObject
* 版权声明 网宿科技, 版权所有 违者必究
*
* <br> Copyright: Copyright (c) 2018
* <br> Company:网宿科技
* <br> @author Administrator
* <br> @description 功能描述
* <br> 2018-11-13 20:34:52
*/
/**
*
*/
package config.response;
/**
* 响应对象。
*
*/
public class ResponseObject<T> {
/**
* 状态码
*/
private String status;
/**
* 描述信息
*/
private String message;
/**
* 错误信息
*/
private String errorMessage;
/**
* 数据对象
*/
private T dataView;
public ResponseObject(String code, String message, T value) {
this.status = code;
this.message = message;
this.dataView = value;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public T getDataView() {
return dataView;
}
public void setDataView(T dataView) {
this.dataView = dataView;
}
}
@@ -0,0 +1,53 @@
/*
* @(#) ResponseConfiguration
* 版权声明 黄志军, 版权所有 违者必究
*
* <br> Copyright: Copyright (c) 2018
* <br> Company:黄志军
* <br> @author selfImpr
* <br> 2018-05-31 14:59:23
* <br> @description
*
*
*/
package config.response;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJacksonValue;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.AbstractMappingJacksonResponseBodyAdvice;
/**
* 这里通过一个注解和继承的方式,对所有出控制器(被某一个注解标注的类) - 这里自定了一个注解为TestResponse
* 对这种类进行参数的处理
* 好像这个注解还有叠加的作用....
* 这个注解也可以作为异常处理的操作。即在每个方法上面添加处理的class。还想这样很麻烦啊,还不如用异常处理器
* @author 志军
*/
@ControllerAdvice
public class ResponseProcess extends AbstractMappingJacksonResponseBodyAdvice {
/**
* 这个注解好像是必须捕获ResponseBody这个解决才会进行执行,@ResponseBody表明这个返回的东西是在报文里面,
* 且如果不配置转换器,spring会自动提供7个,但是如果我们想规定顺序就要自己配置
*/
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
System.out.println( returnType.getMethod().getName());
return returnType.hasMethodAnnotation(ResponseBody.class);
}
@Override
protected void beforeBodyWriteInternal(MappingJacksonValue bodyContainer, MediaType contentType, MethodParameter returnType,
ServerHttpRequest request, ServerHttpResponse response) {
Object value = bodyContainer.getValue();
ResponseObject<Object> object = new ResponseObject<>("200", "调度成功", value);
bodyContainer.setValue(object);
}
}
@@ -0,0 +1,25 @@
package controller;
import config.propertiesScan.PropertiesScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author selfimpr
* @description 测试SpringConfig利用注解来实现properties配置文件的读取
* @date 2017/11/11 21:26
*/
@Controller
public class PropertiesGetController {
@Autowired
private PropertiesScan propertiesConfig;
@RequestMapping("/get/properties")
public void getProperties() {
System.out.println(propertiesConfig.getIsBorder());
System.out.println(propertiesConfig.getBorderColor());
}
}
@@ -0,0 +1,47 @@
package listener;
import org.apache.log4j.Logger;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* 处理Session创建和消亡的类,这边通过<code>@WebListener</code>注解直接声明为监听器
* @author 志军
*/
@WebListener
public class TestHttpSessionListener implements HttpSessionListener {
private Logger logger = Logger.getLogger(HttpSessionListener.class);
@Override
public void sessionCreated(HttpSessionEvent se) {
SessionListenerTask sessionListenerTask = new SessionListenerTask();
HttpSession session = se.getSession();
// 设置session过期时间 --这种方式并不科学
se.getSession().setMaxInactiveInterval(20);
logger.debug("session创建时间:"+session.getCreationTime());
//为了让页面加载看起来更流畅,这里模拟了两个情况,一个是用线程实现不等待,一个是加载数据库等待
if(SessionListenerTask.isIsFirst()){
sessionListenerTask.run();
SessionListenerTask.setIsFirst(false);
}else{
//这里是同步情况
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("session 加载开始,时间为:" + System.currentTimeMillis());
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
se.getSession().getCreationTime();
System.out.println("session过期了");
}
}
+28
View File
@@ -0,0 +1,28 @@
package model;
import java.io.InputStream;
public class FileItem {
private String fileName;
private InputStream inputStream;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
}
+263
View File
@@ -0,0 +1,263 @@
package util;
import com.google.common.collect.Lists;
import model.FileItem;
import org.springframework.util.CollectionUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
/**
*
* @author huangzj1
*/
public class FileUtil {
private static final byte[] BUF = new byte[1024];
private static final int BUF_SIZE = 1024;
public static void deleteFile(String filePath) {
File file = new File(filePath);
if (!file.exists()) {
throw new RuntimeException("文件不存在");
}
file.delete();
}
/**
* 支持输入流存储到对应文件夹下,仅对文件夹有效
* @param fileItems 输入流、文件名 数组
* @param dirPath 文件夹路径
*/
public static void storeFiles(List<FileItem> fileItems, String dirPath) {
File file = new File(dirPath);
if (!file.exists() && !file.isDirectory()) {
file.mkdir();
}
fileItems.forEach(fileItem -> {
File fileItemFile = new File(dirPath + File.separator + fileItem.getFileName());
FileOutputStream fileOutputStream;
try {
//创建文件
fileItemFile.createNewFile();
fileOutputStream = new FileOutputStream(fileItemFile);
int len;
while ((len = fileItem.getInputStream().read(BUF, 0, BUF_SIZE)) != -1) {
fileOutputStream.write(BUF, 0, len);
}
fileOutputStream.close();
fileItem.getInputStream().close();
} catch (IOException e) {
throw new RuntimeException("生成文件错误");
}
});
}
public static boolean fileExist(String filePath){
File file = new File(filePath);
return file.exists();
}
public static boolean isFile(String filePath){
File file = new File(filePath);
if ( file.exists()){
return file.isFile();
}
return false;
}
public static boolean isDir(String filePath){
File file = new File(filePath);
if ( file.exists()){
return file.isDirectory();
}
return false;
}
/**
* 文件已存在或者创建成功返回true
* 文件不存在或者非文件(文件夹)或者创建失败,返回false
*/
public static boolean createFile(String filePath){
if(fileExist(filePath)){
return isFile(filePath);
}
File file = new File(filePath);
try {
return file.createNewFile();
} catch (IOException e) {
return false;
}
}
/**
* 创建并获取一个File对象
* 如果是文件、创建成功返回对应的文件对象
* 其他情况直接返回null.
*/
public static File createGetFile(String filePath){
if(fileExist(filePath)){
if ( isFile(filePath)){
return new File(filePath);
}
}
File file = new File(filePath);
try {
boolean result = file.createNewFile();
if (result){
return file;
}
} catch (IOException e) {
return null;
}
return null;
}
/**
* 文件转换成byte数组
*/
public static byte[] fileToByte(String filePath) {
FileInputStream in = null;
try {
in = new FileInputStream(new File(filePath));
byte[] bytes = new byte[in.available()];
in.read(bytes);
return bytes;
} catch (IOException e) {
throw new RuntimeException("转换失败",e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* byte数组写入文件
*/
public static void bytesToFile(String filePath,byte[] content){
FileOutputStream out = null;
try {
out = new FileOutputStream(new File(filePath));
out.write(content);
out.flush();
} catch (IOException e) {
throw new RuntimeException("写入失败",e);
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 拿到文件夹下面的所有文件夹(包括它自己)
*/
public static List<File> findAllDirFromDir(String dirPath){
File dir = new File(dirPath);
if(!dir.exists() || !dir.isDirectory()){
throw new RuntimeException("非文件夹或者文件夹位置错误");
}
List<File> result = findDir(dir);
result.add(dir);
return result;
}
private static List<File> findDir(File file ){
List<File> list = Lists.newArrayList();
for(File child : Objects.requireNonNull(file.listFiles())){
if(child.isDirectory()){
list.add(child);
List<File> tempList = findDir(child);
if(!CollectionUtils.isEmpty(tempList)){
list.addAll(tempList);
}
}
}
return list;
}
/**
* 拿到文件夹下面的所有空文件夹
*/
public static List<File> findAllEmptyDirFromDir( String dirPath){
List<File> list = Lists.newArrayList();
File dir = new File(dirPath);
if(!dir.exists() || !dir.isDirectory()){
throw new RuntimeException("非文件夹或者文件夹位置错误");
}
List<File> allList = findAllDirFromDir(dirPath);
for(File dirFile:allList){
if(isEmptyFile(dirFile)){
list.add(dirFile);
}
}
return list;
}
/**
* 通过目录获取目录下所有的文件
*/
public static List<File> findAllFile(File dir){
List<File> list = Lists.newArrayList();
for (File file : Objects.requireNonNull(dir.listFiles())){
if(file.isFile()){
list.add(file);
}else{
List<File> tempList = findAllFile(file);
if(!CollectionUtils.isEmpty(tempList)){
list.addAll(tempList);
}
}
}
return list;
}
private static boolean isEmptyFile(File dir) {
List<File> child = findAllFile(dir);
return CollectionUtils.isEmpty(child);
}
/**
* 拿到文件夹下面的所有非空文件夹
*/
public static List<File> findAllNotEmptyDirFromDir( String dirPath){
List<File> list = Lists.newArrayList();
File dir = new File(dirPath);
if(!dir.exists() || !dir.isDirectory()){
throw new RuntimeException("非文件夹或者文件夹位置错误");
}
List<File> allList = findAllDirFromDir(dirPath);
for(File dirFile:allList){
if(!isEmptyFile(dir)){
list.add(dirFile);
}
}
return list;
}
}
+4
View File
@@ -0,0 +1,4 @@
#spring 提供的Environment会加载application.properties和application-$(profile).properties文件。
#这里就是测试一下
#用于做quartz定时任务
cron=0 0 3/1 3 * ? *
@@ -0,0 +1,2 @@
area_id=\u9EC4\u5FD7\u519B
local_request_id=JOINT_THEME
@@ -0,0 +1 @@
b=1