From 456f0be8b51aa23d5afe598970996dd1cf5cb930 Mon Sep 17 00:00:00 2001 From: huangzj Date: Fri, 22 May 2020 18:02:41 +0800 Subject: [PATCH] =?UTF-8?q?feat(Java=5FSpringExample):=20=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E5=B7=A5=E7=A8=8B(=E4=BB=A3=E7=A0=81=E6=9C=89?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=8C=E5=85=88=E6=8F=90=E4=BA=A4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 4 + pom.xml | 542 ++++++++++++++++++ .../FreeMarkerConfigurationAdapter.java | 113 ++++ src/main/java/config/AopComponentLoder.java | 36 ++ .../java/config/CacheSetFromProperty.java | 37 ++ .../java/config/ContextComponentLoader.java | 200 +++++++ src/main/java/config/MvcComponentLoader.java | 291 ++++++++++ src/main/java/config/WebInitializer.java | 177 ++++++ .../java/extention/AlarmTplConfiguration.java | 15 + src/main/java/filter/FilterDelegator.java | 39 ++ .../java/filter/WelcomeHandlingFilter.java | 68 +++ .../java/listener/SessionListenerTask.java | 37 ++ src/main/java/scheduler/JobScheduler.java | 74 +++ src/main/java/scheduler/adapter/BaseJob.java | 8 + .../java/scheduler/adapter/JobAdapter.java | 172 ++++++ src/main/java/util/MessageUtils.java | 26 + src/main/resources/cache/ehcache.xml | 94 +++ 17 files changed, 1933 insertions(+) create mode 100644 Readme.md create mode 100644 pom.xml create mode 100644 src/main/java/adapter/FreeMarkerConfigurationAdapter.java create mode 100644 src/main/java/config/AopComponentLoder.java create mode 100644 src/main/java/config/CacheSetFromProperty.java create mode 100644 src/main/java/config/ContextComponentLoader.java create mode 100644 src/main/java/config/MvcComponentLoader.java create mode 100644 src/main/java/config/WebInitializer.java create mode 100644 src/main/java/extention/AlarmTplConfiguration.java create mode 100644 src/main/java/filter/FilterDelegator.java create mode 100644 src/main/java/filter/WelcomeHandlingFilter.java create mode 100644 src/main/java/listener/SessionListenerTask.java create mode 100644 src/main/java/scheduler/JobScheduler.java create mode 100644 src/main/java/scheduler/adapter/BaseJob.java create mode 100644 src/main/java/scheduler/adapter/JobAdapter.java create mode 100644 src/main/java/util/MessageUtils.java create mode 100644 src/main/resources/cache/ehcache.xml diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..040fa11 --- /dev/null +++ b/Readme.md @@ -0,0 +1,4 @@ +##工程作用 + +##更新记录 +2020/5/22 : 创建工程(代码有问题,先提交) \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..94654b3 --- /dev/null +++ b/pom.xml @@ -0,0 +1,542 @@ + + 4.0.0 + Java_SpringExample + Java_SpringExample + war + 1.0.0 + Java_SpringExample + http://maven.apache.org + + + + + UTF-8 + 1.7 + 7.0 + 4.11 + 3.0 + 2.3 + 1.7.12 + 1.6.2 + 2.3.2 + 4.3.1.RELEASE + 10.2.0.4 + yyyyMMddHHmmss + 3.3.5 + + + + + + junit + junit + 3.8.1 + test + + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + 2.8.7 + + + + + javax.servlet + jstl + 1.2 + + + javax + javaee-web-api + ${javax.version} + provided + + + + + + org.springframework + spring-aop + ${org.springframework.version} + + + org.springframework + spring-beans + ${org.springframework.version} + + + org.springframework + spring-context + ${org.springframework.version} + + + org.springframework + spring-core + ${org.springframework.version} + + + org.springframework + spring-expression + ${org.springframework.version} + + + org.springframework + spring-orm + ${org.springframework.version} + + + org.springframework + spring-tx + ${org.springframework.version} + + + org.springframework + spring-web + ${org.springframework.version} + + + org.springframework + spring-webmvc + ${org.springframework.version} + + + org.springframework + spring-context-support + ${org.springframework.version} + + + + + org.springframework + spring-aspects + ${org.springframework.version} + + + org.aspectj + aspectjrt + 1.6.11 + + + org.aspectj + aspectjweaver + 1.8.9 + + + cglib + cglib + 2.1_3 + + + + + org.slf4j + slf4j-api + ${slf4j.version} + compile + + + org.slf4j + slf4j-log4j12 + ${slf4j.version} + + + org.apache.logging.log4j + log4j-api + ${log4j.version} + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + + + + com.alibaba + fastjson + 1.2.54 + + + + dom4j + dom4j + 1.6.1 + + + + + + + + + + + + + commons-beanutils + commons-beanutils + 1.8.3 + + + + + + org.apache.shiro + shiro-core + 1.2.2 + + + + javax.servlet.jsp.jstl + jstl-api + 1.2 + + + javax.servlet + servlet-api + + + javax.servlet.jsp + jsp-api + + + + + + org.glassfish.web + jstl-impl + 1.2 + + + javax.servlet + servlet-api + + + javax.servlet.jsp + jsp-api + + + javax.servlet.jsp.jstl + jstl-api + + + + + + + + + + org.mybatis + mybatis + 3.4.1 + + + + org.mybatis + mybatis-spring + 1.3.1 + + + + + + tk.mybatis + mapper + 3.3.9 + + + + + + org.mybatis.generator + mybatis-generator-core + 1.3.5 + + + + + + net.coobird + thumbnailator + 0.4.8 + + + + + org.jboss + jandex + 1.2.2.Final + + + org.javassist + javassist + 3.18.2-GA + + + + + + + com.itextpdf + itextpdf + 5.5.11 + + + com.itextpdf + itext-asian + 5.2.0 + + + com.itextpdf.tool + xmlworker + 5.5.11 + + + + + + + + + + + net.sf.ehcache + ehcache + 2.10.2 + + + + + org.apache.commons + commons-configuration2 + 2.2 + + + + + + commons-codec + commons-codec + 1.9 + + + + + commons-beanutils + commons-beanutils + 1.9.3 + + + + + + org.apache.commons + commons-dbcp2 + 2.2.0 + + + + + + commons-dbutils + commons-dbutils + 1.7 + + + + + org.apache.commons + commons-digester3 + 3.2 + + + + + commons-fileupload + commons-fileupload + 1.3.3 + + + + + org.apache.httpcomponents + httpclient + 4.5.6 + + + + + + org.apache.commons + commons-compress + 1.18 + + + + + + commons-io + commons-io + 2.6 + + + + + + org.apache.commons + commons-lang3 + 3.4 + + + org.apache.poi + poi + 3.15 + + + org.apache.poi + poi-ooxml + 3.15 + + + org.apache.poi + poi-ooxml + 3.15 + + + com.google.code.google-collections + google-collect + snapshot-20080530 + + + com.google.guava + guava + 19.0 + + + com.google.guava + guava + 19.0 + + + org.springframework + spring-web + 4.3.7.RELEASE + + + com.google.zxing + core + 2.2 + + + com.google.zxing + core + 2.2 + + + com.google.zxing + core + 2.2 + + + com.fasterxml.jackson.core + jackson-databind + 2.7.2 + + + com.belerweb + pinyin4j + 2.5.0 + + + + + + org.freemarker + freemarker + 2.3.23 + + + + org.quartz-scheduler + quartz + 2.2.1 + + + + + redis.clients + jedis + 2.7.1 + + + org.springframework.data + spring-data-redis + 1.6.2.RELEASE + + + + + + org.hibernate + hibernate-core + 5.3.7.Final + + + + + org.hibernate + hibernate-validator + 6.0.13.Final + + + + + + + + Java_SpringExample + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + maven-war-plugin + 2.4 + + true + + + + + + + + + + src/main/java + + **/*.cache.properties + **/*.xml + * + + false + + + src/main/resources + + + + diff --git a/src/main/java/adapter/FreeMarkerConfigurationAdapter.java b/src/main/java/adapter/FreeMarkerConfigurationAdapter.java new file mode 100644 index 0000000..c1a276f --- /dev/null +++ b/src/main/java/adapter/FreeMarkerConfigurationAdapter.java @@ -0,0 +1,113 @@ +/* + * @(#) FreeMarkerConfigurationAdapter + * 版权声明 黄志军, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:黄志军 + *
@author selfImpr + *
2018-05-23 11:34:00 + *
@description 通过这个适配器获取到freeMaker的配置类信息,具备默认配置 + * + * + */ + +package adapter; + +import freemarker.template.Configuration; +import freemarker.template.TemplateExceptionHandler; +import freemarker.template.Version; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +/** + * author: selfImpr

+ * description:
+ *
+ * 该适配器用于生成配置信息相关的类
+ * 支持传入配置类或其子类
+ * 该适配器希望简化配置过程,包括设置一些默认的参数,当然这些参数是可以外部设置 + *



+ * Date: 2018/5/23/023 15:45 + */ +public class FreeMarkerConfigurationAdapter { + + //配置器的类路径 + private String filePath; + //默认路径配置 + private final String defaultPath = "tpl"; + + //编码配置 + private String encoding; + //默认编码配置 + private final String defaultEncoding = "UTF-8"; + + //错误解决类配置 + private TemplateExceptionHandler exceptionHandler; + //默认错误解决类配置 + private final TemplateExceptionHandler defaultExceptionHandler = TemplateExceptionHandler.RETHROW_HANDLER; + + public FreeMarkerConfigurationAdapter() { + } + + public FreeMarkerConfigurationAdapter(String filePath, String encoding, TemplateExceptionHandler exceptionHandler) { + this.filePath = filePath; + this.encoding = encoding; + this.exceptionHandler = exceptionHandler; + } + + /** + * + * 我们使用反射的机制,构造有参数的构造器,作为一个适配器,接受生成继承Configuration的子类对象

+ * 这里使用了反射的机制,可以了解一下 + * @param clazz + * @param + * @return + * @throws IOException + * @throws IllegalAccessException + * @throws InstantiationException + * @throws NoSuchMethodException + * @throws InvocationTargetException + */ + public T createConfiguration(Class clazz) throws IOException, IllegalAccessException, + InstantiationException, NoSuchMethodException, InvocationTargetException { + Constructor constructor = clazz.getDeclaredConstructor(new Class[]{Version.class}); + constructor.setAccessible(true); //设置语法检查? + T t = (T) constructor.newInstance(Configuration.VERSION_2_3_22); + + + // Configuration configuration = new Configuration(Configuration.VERSION_2_3_22); + Resource resource1 = new ClassPathResource(defaultPath); + t.setDirectoryForTemplateLoading(resource1.getFile()); + t.setDefaultEncoding(defaultEncoding); + t.setTemplateExceptionHandler(defaultExceptionHandler); + if (StringUtils.isNotEmpty(filePath)) { + Resource resource = new ClassPathResource(filePath); + t.setDirectoryForTemplateLoading(resource1.getFile()); + } + if (StringUtils.isNotEmpty(encoding)) { + t.setDefaultEncoding(encoding); + } + if (exceptionHandler != null) { + t.setTemplateExceptionHandler(exceptionHandler); + } + + return t; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } + + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + public void setExceptionHandler(TemplateExceptionHandler exceptionHandler) { + this.exceptionHandler = exceptionHandler; + } +} diff --git a/src/main/java/config/AopComponentLoder.java b/src/main/java/config/AopComponentLoder.java new file mode 100644 index 0000000..09fccca --- /dev/null +++ b/src/main/java/config/AopComponentLoder.java @@ -0,0 +1,36 @@ +package config; + +import com.springmvc.config.aop.SensitiveAop; +import com.springmvc.config.aop.aopClass; +import com.springmvc.config.support.RequestLimitAspect; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +/** + * Created by Administrator on 2017/7/26. + * 启动AspectJ自动代理 + */ +@Configuration +@EnableAspectJAutoProxy +@ComponentScan +public class AopComponentLoder { + + //在这里注册切面的bean + @Bean + public aopClass aopClass() { + return new aopClass(); + } + + @Bean + public SensitiveAop sensitiveAop() { + return new SensitiveAop(); + } + + @Bean + public RequestLimitAspect getRequestLimitAspect() { + return new RequestLimitAspect(); + } + +} diff --git a/src/main/java/config/CacheSetFromProperty.java b/src/main/java/config/CacheSetFromProperty.java new file mode 100644 index 0000000..310d5a6 --- /dev/null +++ b/src/main/java/config/CacheSetFromProperty.java @@ -0,0 +1,37 @@ +package config; + +import net.sf.ehcache.CacheManager; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.ehcache.EhCacheCacheManager; +import org.springframework.cache.ehcache.EhCacheManagerFactoryBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; + +/** + * @author : selfimpr + * @description: 配置cache,通过xml文件规定cache的规则 + * 然后声明为一个bean,通过注解来使用cache + * @date : 2017/11/3 10:52 + */ +@Configuration +@EnableCaching +public class CacheSetFromProperty { + + @Bean + public EhCacheCacheManager cacheCacheManager(CacheManager ehCacheManagerFactoryBean){ + return new EhCacheCacheManager(ehCacheManagerFactoryBean); + } + + + @Bean + public EhCacheManagerFactoryBean ehCacheManagerFactoryBean(){ + EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean(); + //通过xml配置cache的命名空间和规则 + ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("cache/ehcache.xml")); + //设置缓存工厂为单例,否则会报错。 + ehCacheManagerFactoryBean.setShared(true); + return ehCacheManagerFactoryBean; + } + +} diff --git a/src/main/java/config/ContextComponentLoader.java b/src/main/java/config/ContextComponentLoader.java new file mode 100644 index 0000000..568af76 --- /dev/null +++ b/src/main/java/config/ContextComponentLoader.java @@ -0,0 +1,200 @@ +package config; + + +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.mapper.MapperScannerConfigurer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.transaction.annotation.EnableTransactionManagement; +import org.springframework.web.context.WebApplicationContext; +import redis.clients.jedis.JedisPoolConfig; + +import javax.sql.DataSource; +import java.io.IOException; +import java.util.Properties; + + +/** + * @author 志军 + * 用@Configuration注解该类,等价 与XML中配置beans;用@Bean标注方法等价于XML中配置bean. + * 相当于applicationContext.xml文件 + * + * 1.自动扫描web包 ,将带有注解的类 纳入spring容器管理 + * 2.引入jdbc配置文件 + * 3.dataSource 配置 + * 4.mybatis文件配置,扫描所有mapper文件 + * 5.spring与mybatis整合配置,扫描所有dao + * 6.对dataSource 数据源进行事务管理 + * 7.配置使Spring采用CGLIB代理 + * 8.启用对事务注解的支持 + */ + @Configuration + @EnableTransactionManagement + @ComponentScan +public class ContextComponentLoader { + + @Autowired + private SqlSessionFactory sqlSessionFactory; + + /** + * 配置数据源 + */ + @Bean + public DataSource dataSource() { + //这边数据库的配置需要根据对应的地址进行修改 + DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(); + driverManagerDataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver"); + driverManagerDataSource.setUrl("jdbc:oracle:thin:@127.0.0.1:3306:ORCL"); + driverManagerDataSource.setUsername("admin"); + driverManagerDataSource.setPassword("admin"); + //可以配置数据池的其他东西 + return driverManagerDataSource; + } + + @Bean + public SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource x) { + SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); + //設置dataSource + sqlSessionFactoryBean.setDataSource(x); + Properties properties = new Properties(); + PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver(); + Resource[] resources = null; + try { + resources = pathMatchingResourcePatternResolver.getResources("dao/*.xml"); + } catch (IOException e) { + e.printStackTrace(); + } + sqlSessionFactoryBean.setMapperLocations(resources); + sqlSessionFactoryBean.setConfigurationProperties(properties); + //全局设置返回的结果map不把null的参数去掉。这个好像局部设置会比较好一点 + org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(); + configuration.setCallSettersOnNulls(true); + sqlSessionFactoryBean.setConfiguration(configuration); + try { + sqlSessionFactoryBean.afterPropertiesSet(); + } catch (Exception e) { + e.printStackTrace(); + } + return sqlSessionFactoryBean; + } + + /** + * 配置mapper的掃描類 + */ + @Bean + public MapperScannerConfigurer getMapperScannerConfigurer() { + MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); + Properties pro = new Properties(); + /**這裡不是用Properties类来接收属性???*/ +// pro.setProperty("basePackage","com.springmvc.test.mapper"); +// pro.setProperty("sqlSessionFactoryBeanName","sqlSessionFactory"); + /**mapper和dao放在一个包下面*/ + /**setBasePackage的方法只能设置一个地址, + * 扫描mapper时找不到对应的Resposity时会报错, + * 但是扫描到Resposity没扫描到mapper不会报错*/ + mapperScannerConfigurer.setBasePackage("dao"); +// mapperScannerConfigurer.setBasePackage("com.springmvc.test.dao"); +// mapperScannerConfigurer.setSqlSessionFactory(sqlSessionFactory); + mapperScannerConfigurer.setSqlSessionFactoryBeanName("getSqlSessionFactoryBean"); + + + try { + return mapperScannerConfigurer; + } catch (Exception ex) { + System.out.println("发生错误"); + ex.printStackTrace(); + } + + return mapperScannerConfigurer; + } + + /** + * 配置mybatis的事务管理 + */ + @Bean + public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) { + DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); + dataSourceTransactionManager.setDataSource(dataSource); + return dataSourceTransactionManager; + } + + + /** + * PersistenceExceptionTranslationPostProcessor是一个 + bean 后置处理器(bean post-processor),它会在所有拥 + 有@Repository注解的类上添加一个通知器(advisor),这样就会 + 捕获任何平台相关的异常并以Spring非检查型数据访问异常的形式重 + 新抛出。 + * */ + @Bean + public BeanPostProcessor persistenceTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + + /** + * 配置redis 的数据源、数据连接池、事务 + */ + @Bean(name = "jedisPoolConfig") + public JedisPoolConfig createJedisPoolConfig() { + JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); + // #最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。 + jedisPoolConfig.setMaxIdle(300); + // #连接池的最大数据库连接数。设为0表示无限制 + jedisPoolConfig.setMaxTotal(600); + // #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。 + jedisPoolConfig.setMaxWaitMillis(5000); + // #在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的; + jedisPoolConfig.setTestOnBorrow(true); + return jedisPoolConfig; + } + + @Bean(name = "jedisConnectionFactory") + public JedisConnectionFactory createJedisConnectionFactory(WebApplicationContext context) { + JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(); + jedisConnectionFactory.setHostName("127.0.0.1"); + jedisConnectionFactory.setPort(6379); + + //redis好像是只有一个用户,默认是没有密码的,在控制台设置密码好像是暂时的,第二次重启的时候这个密码就会失效 + //如果redis没有密码,就不要给这个参数进行设值操作,不然会报错,而且redis桌面应用中的密码和链接redis客户端的密码好像也会冲突 + jedisConnectionFactory.setPassword("123456"); + //连接池配置 + jedisConnectionFactory.setPoolConfig((JedisPoolConfig) context.getBean("jedisPoolConfig")); + return jedisConnectionFactory; + } + + + /** + * redis操作模版,使用该对象可以操作redis + */ + @Bean(name = "redisTemplate") + public RedisTemplate createRedisTemplate(WebApplicationContext context) { + RedisTemplate redisTemplate = new RedisTemplate(); + redisTemplate.setConnectionFactory((RedisConnectionFactory) context.getBean("jedisConnectionFactory")); + // 如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!! + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); + redisTemplate.setHashKeySerializer(new StringRedisSerializer()); + redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); + //开启事务 + redisTemplate.setEnableTransactionSupport(true); + return redisTemplate; + } + + +} + diff --git a/src/main/java/config/MvcComponentLoader.java b/src/main/java/config/MvcComponentLoader.java new file mode 100644 index 0000000..50fe74b --- /dev/null +++ b/src/main/java/config/MvcComponentLoader.java @@ -0,0 +1,291 @@ +package config; + +import adapter.FreeMarkerConfigurationAdapter; +import extention.AlarmTplConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.FileSystemResource; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.filter.CharacterEncodingFilter; +import org.springframework.web.multipart.MultipartResolver; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.*; +import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; +import org.springframework.web.servlet.view.InternalResourceViewResolver; +import scheduler.JobScheduler; +import scheduler.adapter.BaseJob; +import scheduler.adapter.JobAdapter; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.text.ParseException; +import java.util.List; +import java.util.Properties; + +/** + * Created by com on 2017/7/25. + * 配置自动加载注解类 + * + * 没有代码配置出现的情况 + * + * 没有配置视图解析器。如果这样的话, Spring默认会使 + 用BeanNameView-Resolver,这个视图解析器会查找ID与视 + 图名称匹配的bean,并且查找的bean要实现View接口,它以这样 + 的方式来解析视图。 + 没有启用组件扫描。这样的结果就是, Spring只能找到显式声明 + 在配置类中的控制器。 + 这样配置的话, DispatcherServlet会映射为应用的默认 + Servlet,所以它会处理所有的请求,包括对静态资源的请求,如 + 图片和样式表(在大多数情况下,这可能并不是你想要的效 + 果)。 + * + * + * spring Mvc配置(相当于spring-servlet.xml) + * 1.Json返回格式化转换 + * 2.设置全局日期参数的字符串表示格式 + * 3.激活@Controller模式 + * 4.配置拦截器 + * 5.类名到视图名的自动映射 + * 6.对模型视图名称的解析 + * + */ +@Configuration +@EnableWebMvc +@ComponentScan({"config"})//启动自动扫描注解 +public class MvcComponentLoader extends WebMvcConfigurerAdapter { + + + /** + * 这里是配置转换器的方法,我们使用@ControllerAdvice需要这个配置,添加我们的转换器 + */ + // @Bean + // public HttpMessageConverterBuilder httpMessageConverterBuilder() { + // return new HttpMessageConverterBuilder(); + // } + // + // @Override + // public void configureMessageConverters(List> converters) { + // converters.addAll(httpMessageConverterBuilder().buildHttpMessageConverters()); + // } + + /** + * 把异常处理器作为一个bean返回,会把spring默认的异常处理器覆盖,这样的做法是在说你的容器只想托管给一个异常处理器来处理 + * @return + */ + // @Bean + // public MyExceptionHandler getExceptionHandler() { + // return new MyExceptionHandler(); + // } + + /** + * 如果我们需要配置多个异常处理器的话, 我们可以在这里面进行异常处理器的注册和他的顺序的处理 + * @param exceptionResolvers + */ + @Override + public void extendHandlerExceptionResolvers(List exceptionResolvers) { + // exceptionResolvers.add(new MyExceptionHandler()); + // ... + } + + /** + * 这边应该是配置的才是正确的适配器 + */ + @Bean + public JobScheduler getJobScheduler(WebApplicationContext context) throws ParseException { + JobScheduler jobScheduler = new JobScheduler(); + JobAdapter jobAdapter = new JobAdapter((BaseJob) context.getBean("myJob"), "myJob", "cron"); + jobScheduler.addJob(jobAdapter); + //在调用这个方法之前,所有的配置都没有被加入到定时器中,也就是说一切还没尘埃落定 + jobScheduler.afterProperties(); + return jobScheduler; + } + + /** + * 错误的适配器事例 + */ + // @Bean(name = "triggerAdapter") + // public SchedulerCronTriggerAdapter getSchedulerCronTriggerAdapter(WebApplicationContext webApplicationContext) { + // SchedulerCronTriggerAdapter schedulerCronTriggerAdapter = new SchedulerCronTriggerAdapter(webApplicationContext); + // //作为适配器,我应该自己去判断他的类型 + // MyJobDetail alarmSendJob = new MyJobDetail(); + // schedulerCronTriggerAdapter.setQuartzJobBeans(alarmSendJob); + // schedulerCronTriggerAdapter.createTriggers(); + // // webApplicationContext.getEnvironment().getProperty("cronRunTime"); + // return schedulerCronTriggerAdapter; + // } + // + // @Bean + // public SchedulerFactoryBean getSchedulerFactoryBean(WebApplicationContext webApplicationContext) { + // SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); + // //设置application和他的key,这个地方是为了这继承的那个方法里面得到scheduler,进而得到applicationContext + // schedulerFactoryBean.setApplicationContextSchedulerContextKey("application"); + // schedulerFactoryBean.setApplicationContext(webApplicationContext); + // List triggers = ((SchedulerCronTriggerAdapter) webApplicationContext.getBean("triggerAdapter")).getTriggers(); + // //因为传进去的是--可变参数--,他是可以支持原生数组的 + // Trigger[] triggers1 = new Trigger[]{}; + // schedulerFactoryBean.setTriggers(triggers.toArray(triggers1)); + // return schedulerFactoryBean; + // } + + + // /** + // * 配置一个trigger作为bean,当然这个trigger还可以是别的类型的 + // * @return + // */ + // @Bean(name = "cronTriggerFactoryBean") + // public CronTriggerFactoryBean getCronTriggerFactoryBean() { + // CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean(); + // JobDetail jobDetail = newJob(MyJobDetail.class).build(); + // cronTriggerFactoryBean.setJobDetail(jobDetail); + // cronTriggerFactoryBean.setCronExpression("0/5 * * * * ? "); + // return cronTriggerFactoryBean; + // } + // + // /** + // * 使用这个trigger的scheduler的配置,也就是定时器的配置,spring原生配置 + // * @param webApplicationContext + // * @return + // */ + // @Bean + // public SchedulerFactoryBean getSchedulerFactoryBean(WebApplicationContext webApplicationContext) { + // SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); + // Trigger ctfb = (Trigger) webApplicationContext.getBean("cronTriggerFactoryBean"); + // schedulerFactoryBean.setTriggers((Trigger) ctfb); + // return schedulerFactoryBean; + // } + + /** + * author: selfImpr

+ * description:

如何去使用一个配置型的工具(来自尚峰的建议):
+ * 1.查阅官网,得到大概的用法
+ * 2.下载jar包研究源码,第一步,对所有的类进行归类,比如一个配置型的工具类包,需要配置信息和调用信息
+ * 3.分类完成之后,弄清楚分级的类之间的关系,主要理出一条线,比如我专注用Temple这个类,我就找到这个类相关的继承关系等
+ * 4.查看大概源代码。因为是配置信息,所以要注意得到temple对象的方法中如何使用这些配置信息

+ * freemarker相关问题
+ * 1.为什么不使用配置的引用,而是新建一份配置,增加内存风险?答:配置信息如果被修改等,可能造成多线程并发问题。新建一份配置信息进行 + * temple的生成可能造成内存风险,但是这里运用了cache的方式,减轻了这个风险 + * Date: 2018/5/21/021 9:52 + * @return 返回类型描述 + * @throws Exception 异常说明 + */ + @Bean + public AlarmTplConfiguration AlarmTplConfiguration() throws IOException, InvocationTargetException, + NoSuchMethodException, InstantiationException, IllegalAccessException { + FreeMarkerConfigurationAdapter freeMarkerConfigurationAdapter = new FreeMarkerConfigurationAdapter(); + /** + * 这里的思路是:
+ * 1.类的有一些参数是可以使用默认设置的,我们这边给他一个使用默认设置的机会 + * 2.类的有一些参数也可以是用户来配置的,所以说这里我们提供了一个设置参数的机会 + */ + return freeMarkerConfigurationAdapter.createConfiguration(AlarmTplConfiguration.class); + } + + + /** + * 配置编码过滤器 + */ + @Bean + public CharacterEncodingFilter characterEncodingFilter() { + CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); + characterEncodingFilter.setEncoding("UTF-8"); + return characterEncodingFilter; + } + + /** + * 这是要配置页面过滤,如40X的页面... + * 参考地址:http://blog.csdn.net/projectarchitect/article/details/42463471 + */ + @Bean + public SimpleMappingExceptionResolver simpleMappingExceptionResolver(){ + SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver(); + Properties properties = new Properties(); + properties.setProperty("org.apache.shiro.authz.UnauthenticatedException","success"); + + simpleMappingExceptionResolver.setExceptionMappings(properties); + return simpleMappingExceptionResolver; + } + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addRedirectViewController("/", "/success"); + } + + /** + * + * 如果没有配置 这个request就需要我自己去解析,不然的话,spring会帮助我解析完成 + */ + @Bean + public MultipartResolver multipartResolver() throws IOException { + CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); + multipartResolver.setUploadTempDir(new FileSystemResource("/cache/files")); + //设置文件大小 + multipartResolver.setMaxInMemorySize(1110); + multipartResolver.setMaxInMemorySize(2220); + return multipartResolver; + } + + /**配置视图解析器*/ + @Bean + public ViewResolver viewResolver() { + InternalResourceViewResolver resolve = new InternalResourceViewResolver(); + resolve.setPrefix("/html/"); + resolve.setSuffix(".html"); + resolve.setOrder(0); + resolve.setExposeContextBeansAsAttributes(true); + + return resolve; + } + + /** + * @author : selfimpr + * @description: 好像同一种类型的视图解析器不能配置多个,但是可以配置多个不同类型的视图解析器 + * 参考地址:http://blog.csdn.net/xlxxcc/article/details/51148927 + * @date: 2017/11/17 15:43 + */ + // @Bean + // public InternalResourceViewResolver internalResourceViewResolver(){ + // InternalResourceViewRes olver resolve = new InternalResourceViewResolver(); + // resolve.setPrefix("/html/"); + // resolve.setSuffix(".jsp"); + // resolve.setOrder(1); + // resolve.setExposeContextBeansAsAttributes(true); + // + // return resolve; + // } + + /**配置静态资源的处理*/ + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + /** + * by 黄志军 + * 2017.08.08 + * */ + /**前面的是页面引用的地址,后面的函数是请求的本地资源地址 + * 如果两个地址是不一样,是为了实现安全性,黑客访问页面请求地址时,想访问本地的资源地址, + * 却找不到真是的地址*/ + + /**.setCachePeriod() + * 该方法实现对静态资源的缓存,保证访问的速度和资源的应用率 + * */ + registry.addResourceHandler("/react/**.js").addResourceLocations("/react/"); + /**可以进行多个资源的配置--添加的参数是数组--*/ + registry.addResourceHandler("/css/**.css").addResourceLocations("/css/"); + } + + + /**解释 + * 新的WebConfig类还扩展了WebMvcConfigurerAdapter + 并重写了其configureDefaultServletHandling()方法。通过 + 调用DefaultServlet-HandlerConfigurer的enable()方法, + 我们要求DispatcherServlet将对静态资源的请求转发到Servlet容 + 器中默认的Servlet上,而不是使用DispatcherServlet本身来处理 + 此类请求。 + */ + @Override + public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } +} diff --git a/src/main/java/config/WebInitializer.java b/src/main/java/config/WebInitializer.java new file mode 100644 index 0000000..5c86796 --- /dev/null +++ b/src/main/java/config/WebInitializer.java @@ -0,0 +1,177 @@ +package config; + +import filter.FilterDelegator; +import filter.WelcomeHandlingFilter; +import org.springframework.util.StringUtils; +import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; + +import javax.servlet.*; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.EventListener; +import java.util.List; + +/** + * Created by com on 2017/7/25. + *

+ * 相当于web.xml的加载配置 + */ + +/*** + * FilterRegistration.Dynamic welcomePagFilter = container.addFilter("WelcomePagFilter", new WelcomePagFilter()); + * welcomePagFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); + * 上述是配置过滤器作用的请求. + * 这里已经包装起来了 + */ + +public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { + + + @Override + public void onStartup(ServletContext servletContext) throws ServletException { + super.onStartup(servletContext); + /**配置和监听器*/ + registerServletFilters(servletContext); + registerListeners(servletContext); + // QuartzListener quartzListener = new QuartzListener(); + // servletContext.addListener(quartzListener.getClass()); + } + + + /** + * 配置ContextComponentLoader + */ + @Override + protected Class[] getRootConfigClasses() { + // return new Class[]{ContextComponentLoder.class}; + return new Class[]{}; + } + + + /** + * 配置DispatcherServlet + */ + @Override + protected Class[] getServletConfigClasses() { + return new Class[]{MvcComponentLoader.class}; + } + + /**将DispatcherServlet映射到指定路径 + 配置ServletMappings*/ + @Override + protected String[] getServletMappings() { + return new String[]{"/"}; + } + + + /** + * 在ServletContext中添加过滤器,并把过滤器应用于DispatcherServlet。 + * + * @param servletContext Servlet上下文 + */ + protected void registerServletFilters(ServletContext servletContext) { + List list = new ArrayList<>(); + /**添加基本的过滤器配置,包括欢迎页和编码格式*/ + configServletFilters(list); + for (FilterDelegator filterDelegator : list) { + if (StringUtils.hasText(filterDelegator.getFilterName())) { + registerServletFilter(servletContext, filterDelegator.getFilter(), filterDelegator.getFilterName()); + } else { + registerServletFilter(servletContext, filterDelegator.getFilter()); + } + } + + } + + /** + * 配置DispatcherServlet的过滤器。 + * 添加基本的过滤器配置 + * + * @param servletFilters DispatcherServlet的过滤器 + */ + protected void configServletFilters(List servletFilters) { + /** + * 配置编码格式和欢迎页面 + */ + // servletFilters.add(new filter(new CharacterEncodingFilter("UTF-8"))); + servletFilters.add(new FilterDelegator(new WelcomeHandlingFilter())); + } + + /** + * 在ServletContext中添加过滤器,并把过滤器应用于DispatcherServlet。 + * + * @param servletContext Servlet上下文 + * @param filter 过滤器 + * @param filterName 过滤器名称 + */ + protected final void registerServletFilter(ServletContext servletContext, Filter filter, String filterName) { + FilterRegistration.Dynamic registration = servletContext.addFilter(filterName, filter); + if (registration == null) { + throw new IllegalStateException("Duplicate Filter registration for '" + filterName + "'. Check to ensure the Filter is only " + + "configured once."); + } + registration.setAsyncSupported(isAsyncSupported()); + registration.addMappingForServletNames(getDispatcherTypes(), false, getServletName()); + } + + /** + * 获取过滤器的分发器类型。
+ * 1、支持异步操作时,默认为:DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE、DispatcherType.ASYNC;
+ * 2、不支持异步操作时,默认为:DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE。 + *

+ * + * 参考:
+ * AbstractDispatcherServletInitializer.getDispatcherTypes() + * + * @return DispatcherType集合 + */ + protected final EnumSet getDispatcherTypes() { + EnumSet dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE); + if (isAsyncSupported()) { + dispatcherTypes.add(DispatcherType.ASYNC); + } + configDispatcherTypes(dispatcherTypes); + return dispatcherTypes; + } + + /** + * 配置过滤器的分发器类型。 + * + * @param dispatcherTypes 过滤器的分发器类型 + */ + protected void configDispatcherTypes(EnumSet dispatcherTypes) { + + } + + /** + * 在ServletContext中添加监听器。 + * + * @param servletContext Servlet上下文 + */ + protected final void registerListeners(ServletContext servletContext) { + List> listenerClasses = new ArrayList(); + + // ExcelTempFileListener excelTempFileListener = new ExcelTempFileListener(); + // TestHttpSessionListener testHttpSessionListener = new TestHttpSessionListener(); + + configListenerClasses(listenerClasses); + for (Class listenerClass : listenerClasses) { + servletContext.addListener(listenerClass); + } + /**添加监听器???? --- 2017.08.23----*/ + // servletContext.addListener(excelTempFileListener); + // servletContext.addListener(testHttpSessionListener); + } + + /** + * 配置监听器。 + * + * @param listenerClasses 监听器类 + */ + protected void configListenerClasses(List> listenerClasses) { + + + } + + +} diff --git a/src/main/java/extention/AlarmTplConfiguration.java b/src/main/java/extention/AlarmTplConfiguration.java new file mode 100644 index 0000000..b465ffb --- /dev/null +++ b/src/main/java/extention/AlarmTplConfiguration.java @@ -0,0 +1,15 @@ + + +package extention; + +import freemarker.template.Configuration; +import freemarker.template.Version; + +public class AlarmTplConfiguration extends Configuration { + public AlarmTplConfiguration() { + } + + public AlarmTplConfiguration(Version incompatibleImprovements) { + super(incompatibleImprovements); + } +} diff --git a/src/main/java/filter/FilterDelegator.java b/src/main/java/filter/FilterDelegator.java new file mode 100644 index 0000000..8c96c2f --- /dev/null +++ b/src/main/java/filter/FilterDelegator.java @@ -0,0 +1,39 @@ +package filter; + +import javax.servlet.Filter; + +/** + * 过滤器委托.(过滤器类) + * Created by com on 2017/8/21. + */ +public class FilterDelegator { + private Filter filter; + + private String filterName; + + public FilterDelegator(Filter filter) { + this.filter = filter; + } + + public FilterDelegator(Filter filter, String filterName) { + + this.filter = filter; + this.filterName = filterName; + } + + public Filter getFilter() { + return filter; + } + + public void setFilter(Filter filter) { + this.filter = filter; + } + + public String getFilterName() { + return filterName; + } + + public void setFilterName(String filterName) { + this.filterName = filterName; + } +} diff --git a/src/main/java/filter/WelcomeHandlingFilter.java b/src/main/java/filter/WelcomeHandlingFilter.java new file mode 100644 index 0000000..3ad39d6 --- /dev/null +++ b/src/main/java/filter/WelcomeHandlingFilter.java @@ -0,0 +1,68 @@ +/** + * + */ + +package filter; + +import org.springframework.util.StringUtils; +import util.MessageUtils; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 处理Welcome请求路径的过滤器:在Welcome请求路径的末尾添加/,解决Servlet 3.0+不能以编程方式来配置Welcome页面的问题。 + * + * @author Kison 2017年7月6日 + */ +public class WelcomeHandlingFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + if (!(servletRequest instanceof HttpServletRequest)) { + throw new ServletException("ServletRequest is not a HttpServletRequest"); + } + if (!(servletResponse instanceof HttpServletResponse)) { + throw new ServletException("ServletResponse is not a HttpServletResponse"); + } + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; + + String welcomeRequestUrl = buildWelcomeRequestUrl(request); + String realRequestUrl = request.getRequestURL().toString(); + if (realRequestUrl.equals(welcomeRequestUrl + "/")) { + // 在Welcome请求路径的末尾添加/,解决Servlet 3.0+不能以编程方式来配置Welcome页面的问题 + response.sendRedirect(realRequestUrl + "login/index"); + } else { + filterChain.doFilter(request, response); + } + } + + /** + * 构建Welcome请求路径,示例:http://127.0.0.1:8080/sample + * + * @param request HttpServletRequest + * @return Welcome请求路径 + */ + private String buildWelcomeRequestUrl(HttpServletRequest request) { + String pattern = "{0}://{1}:{2}{3}"; + String scheme = request.getScheme(); + String serverName = request.getServerName(); + String serverPort = String.valueOf(request.getServerPort()); + String contextPath = StringUtils.isEmpty(request.getContextPath()) ? "" : request.getContextPath(); + return MessageUtils.format(pattern, scheme, serverName, serverPort, contextPath); + } + + @Override + public void destroy() { + + } + +} diff --git a/src/main/java/listener/SessionListenerTask.java b/src/main/java/listener/SessionListenerTask.java new file mode 100644 index 0000000..3570dde --- /dev/null +++ b/src/main/java/listener/SessionListenerTask.java @@ -0,0 +1,37 @@ +/* + * @(#) SessionListenerTask + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2018-11-13 20:32:51 + */ + +package listener; + +//可以参考:https://www.cnblogs.com/wcyBlog/p/4657903.html +public class SessionListenerTask implements Runnable{ + + private static boolean IS_FIRST = true; + + public static boolean isIsFirst() { + return IS_FIRST; + } + + public static void setIsFirst(boolean isFirst) { + IS_FIRST = isFirst; + } + + @Override + public void run() { + //模拟线程加载数据库 + try { + Thread.sleep(10000); + System.out.println("数据库取数据结束"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/scheduler/JobScheduler.java b/src/main/java/scheduler/JobScheduler.java new file mode 100644 index 0000000..9f59db8 --- /dev/null +++ b/src/main/java/scheduler/JobScheduler.java @@ -0,0 +1,74 @@ +/* + * @(#) JobScheduler + * 版权声明 黄志军, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:黄志军 + *
@author selfImpr + *
2018-05-25 11:36:07 + *
@description 调度job + * + * + */ + +package scheduler; + +import scheduler.adapter.JobAdapter; +import org.apache.commons.lang3.StringUtils; +import org.quartz.Trigger; +import org.springframework.scheduling.quartz.CronTriggerFactoryBean; +import org.springframework.scheduling.quartz.JobDetailFactoryBean; +import org.springframework.scheduling.quartz.SchedulerFactoryBean; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * 这个调度器也应该是继承调度接口,把job放进来以后,我会生成为一个调度的任务Bean + */ +public class JobScheduler extends SchedulerFactoryBean { + + private List triggers = new ArrayList<>(); + + private List jobAdapters = new ArrayList<>(); + + public void addJob(JobAdapter job) throws ParseException { + if (StringUtils.isNotEmpty(job.getCronExpression())) { + jobAdapters.add(job); + createAndAddTrigger(); + } else { + logger.info("因为你添加的这个job的cron表单式为:" + job.getCronExpression() + "所以这个任务不添加到调用队列"); + } + + } + + private void createAndAddTrigger() { + for (JobAdapter jobAdapter : jobAdapters) { + JobDetailFactoryBean jobDetail = new JobDetailFactoryBean(); + jobDetail.setJobClass(jobAdapter.getClass()); + jobDetail.setName(jobAdapter.getName()); + jobDetail.setGroup(jobAdapter.getGroup()); + jobDetail.afterPropertiesSet(); + CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean(); + // 这个设置名称的这个是不是需要被指定? + cronTriggerFactoryBean.setName(jobAdapter.getTriggerName() == null ? jobAdapter.getName() + UUID.randomUUID().toString() + .replace("-", "") : jobAdapter.getTriggerName()); + cronTriggerFactoryBean.setJobDetail(jobDetail.getObject()); + cronTriggerFactoryBean.setCronExpression(jobAdapter.getCronExpression()); + try { + cronTriggerFactoryBean.afterPropertiesSet(); + } catch (ParseException e) { + logger.error("trigger初始化错误了", e); + } + triggers.add(cronTriggerFactoryBean.getObject()); + } + } + + + public void afterProperties() { + Trigger[] t1 = new Trigger[]{}; + setTriggers(triggers.toArray(t1)); + } +} diff --git a/src/main/java/scheduler/adapter/BaseJob.java b/src/main/java/scheduler/adapter/BaseJob.java new file mode 100644 index 0000000..5a77895 --- /dev/null +++ b/src/main/java/scheduler/adapter/BaseJob.java @@ -0,0 +1,8 @@ + + +package scheduler.adapter; + +public interface BaseJob { + + void doScheduleTask(); +} diff --git a/src/main/java/scheduler/adapter/JobAdapter.java b/src/main/java/scheduler/adapter/JobAdapter.java new file mode 100644 index 0000000..475d637 --- /dev/null +++ b/src/main/java/scheduler/adapter/JobAdapter.java @@ -0,0 +1,172 @@ +/* + * @(#) JobAdapter + * 版权声明 黄志军, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:黄志军 + *
@author selfImpr + *
2018-05-25 11:33:37 + *
@description + * + * + */ + +package scheduler.adapter; + + +import org.apache.log4j.Logger; +import org.quartz.JobExecutionContext; +import org.springframework.scheduling.quartz.QuartzJobBean; + +/** + * jobAdapter 适配器可能是一个需要实现的类也可能是一个制造这个使用类的制造类 + * 明显的,这里就是一个需要实现的类。 + */ +public class JobAdapter extends QuartzJobBean { + + private Logger logger = Logger.getLogger(JobAdapter.class); + + /** + * 需要的job 类的接口

+ * 适配器的目的是跳过new的过程,调用接口去找到他的具体实现类,调用实现类的方法 + */ + private BaseJob baseJob; + + /** + * 跟调度相关的调度任务名称 + */ + private String name; + + /** + * 跟调度相关的调度组的名称 + */ + private String group; + + + /** + * propertis里面的name + */ + private String propertyKey; + + /** + * propertis里面的value + */ + private String propertyValue; + + /** + * job生成的trigger的名称 + */ + private String triggerName; + + /** + * job生成的tigger的group + */ + private String triggerGroup; + + /** + * 表达式 + */ + private String cronExpression; + + public JobAdapter() { + } + + /** + * 三个可能必须参数 + * @param baseJob job实例 + * @param name 名称 + * @param propertyKey 配置表达式的key + */ + public JobAdapter(BaseJob baseJob, String name, String propertyKey) { + this.baseJob = baseJob; + this.name = name; + this.propertyKey = propertyKey; + //这边要怎么去获取,有多找那个方式,但是用spring的方式还是用java的方式? + if (propertyKey != null) { + this.cronExpression = "0 0 3/1 3 * ? * "; + } + } + + /** + * 三个必须参数 + * @param name + * @param propertyValue + * @param baseJob + */ + public JobAdapter(String name, String propertyValue, BaseJob baseJob) { + this.baseJob = baseJob; + this.name = name; + this.propertyValue = propertyValue; + this.cronExpression = propertyValue; + } + + + @Override + protected void executeInternal(JobExecutionContext context) { + try { + baseJob.doScheduleTask(); + } catch (Exception e) { + logger.error(baseJob.getClass().getName() + "该任务不存在", e); + } + } + + public BaseJob getBaseJob() { + return baseJob; + } + + public void setBaseJob(BaseJob baseJob) { + this.baseJob = baseJob; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getGroup() { + return group; + } + + public void setGroup(String group) { + this.group = group; + } + + public String getTriggerName() { + return triggerName; + } + + public void setTriggerName(String triggerName) { + this.triggerName = triggerName; + } + + public String getTriggerGroup() { + return triggerGroup; + } + + public void setTriggerGroup(String triggerGroup) { + this.triggerGroup = triggerGroup; + } + + public String getPropertyKey() { + return propertyKey; + } + + public void setPropertyKey(String propertyKey) { + this.propertyKey = propertyKey; + } + + public String getPropertyValue() { + return propertyValue; + } + + public void setPropertyValue(String propertyValue) { + this.propertyValue = propertyValue; + } + + public String getCronExpression() { + return cronExpression; + } +} diff --git a/src/main/java/util/MessageUtils.java b/src/main/java/util/MessageUtils.java new file mode 100644 index 0000000..191d29e --- /dev/null +++ b/src/main/java/util/MessageUtils.java @@ -0,0 +1,26 @@ +package util; + +import org.slf4j.helpers.MessageFormatter; + +import java.text.MessageFormat; + +/** + * Created by Administrator on 2017/8/21. + * @author 志军 + */ +public class MessageUtils { + /** + * 格式化信息,支持message={0}或message={}格式的信息模板。 + * + * @param pattern 信息模板 + * @param parameters 参数值 + * @return 格式化后的信息 + */ + public static String format(String pattern, Object... parameters) { + try { + return MessageFormat.format(pattern, parameters); + } catch (IllegalArgumentException e) { + return MessageFormatter.arrayFormat(pattern, parameters).getMessage(); + } + } +} diff --git a/src/main/resources/cache/ehcache.xml b/src/main/resources/cache/ehcache.xml new file mode 100644 index 0000000..3eaf74e --- /dev/null +++ b/src/main/resources/cache/ehcache.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file