0
点赞
收藏
分享

微信扫一扫

热部署


1、将springloaded-1.2.5.RELEASE.jar(​​​​http://pan.baidu.com/s/1o7oRq1k​​​​)放在tomcat的bin目录下

2、修改bin目录下的catalina.bat,在第一行加上下面这一句,注意路径可能需要修改一下:

set JAVA_OPTS=-javaagent:E:\apache-tomcat-7.0.55\bin\springloaded-1.2.5.RELEASE.jar -noverify

如此以来,所有的class文件更新都会实时反馈,但是新增的类文件的注解并不能生效

如果是想在eclipse的tomcat中使用,则在run configruation的相应tomcat的arguments的VM arguments中另起一行添加一个变量:-Djavaagent:D:\soft\DevelopSoft\toolsjar\springloaded-1.2.5.RELEASE.jar -noverify  即可


注意eclipse中的tomcat默认是代码修改就会重启的,这和我们的热部署是冲突的,所以我们要禁用tomcat的自动重启:

去掉对号:

 热部署_spring

server.xml的reloadable设为false


热部署_spring_02




3、对于mybatis的xml,暂时用手动来触发更新,可以参考SysUtilsController.java中的refreshMappers方法,手动来触发该方法就会重新加载所有spring配置文件中指定路径的xml


【SysUtilsController】

1 /**
2 *
3 * @ClassName: SysUtilsController
4 * @Description: TODO
5 * @author: liuyx
6 * @date: 2016年1月5日下午5:43:52
7 */
8 @Controller
9 @RequestMapping("/sysUtils")
10 public class SysUtilsController extends BaseController{
11 // 日志记录器
12 private final Logger logger = Logger.getLogger(this.getClass());
13
14 /**
15 *
16 * @Title: refreshMappers
17 * @author:liuyx
18 * @date:2015年12月30日下午6:39:09
19 * @Description: 重新加载所有mapper xml文件
20 * @param request
21 * @return
22 */
23 @RequestMapping("/refreshMappers")
24 @ResponseBody
25 public RetObj refreshMappers(HttpServletRequest request) {
26 MybatisMapperLoadUtil mapperUtil = (MybatisMapperLoadUtil)ComponentFactory.getBean(MybatisMapperLoadUtil.class);
27 try {
28 mapperUtil.getScanner().reloadXML();
29 } catch (Exception e) {
30 // TODO Auto-generated catch block
31 e.printStackTrace();
32 logger.error(e);
33 return new RetObj(false,request);
34 }
35 return new RetObj(true,request);
36 }
37
38 }


【MybatisMapperLoadUtil】① (这个是根据 XML_RESOURCE_PATTERN 所写的路径扫描所有mapper xml)

1 import java.io.IOException;
2 import java.lang.reflect.Field;
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.Set;
6
7 import org.apache.ibatis.builder.xml.XMLMapperBuilder;
8 import org.apache.ibatis.executor.ErrorContext;
9 import org.apache.ibatis.session.Configuration;
10 import org.apache.ibatis.session.SqlSessionFactory;
11 import org.apache.log4j.Logger;
12 import org.springframework.beans.BeansException;
13 import org.springframework.beans.factory.InitializingBean;
14 import org.springframework.context.ApplicationContext;
15 import org.springframework.context.ApplicationContextAware;
16 import org.springframework.context.ConfigurableApplicationContext;
17 import org.springframework.core.io.Resource;
18 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
19 import org.springframework.core.io.support.ResourcePatternResolver;
20
21 /**
22 * 用于重新加载Mapper的工具
23 */
24 public class MybatisMapperLoadUtil implements InitializingBean, ApplicationContextAware {
25 // 日志记录器
26 private final Logger logger = Logger.getLogger(this.getClass());
27 private final HashMap<String, String> mappers = new HashMap<String, String>();
28 private volatile ConfigurableApplicationContext context = null;
29 private volatile Scanner scanner = null;
30
31 @Override
32 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
33 this.context = (ConfigurableApplicationContext) applicationContext;
34 }
35
36 @Override
37 public void afterPropertiesSet() throws Exception {
38 setScanner(new Scanner());
39 /*try {
40
41 new Timer(true).schedule(new TimerTask() {
42 public void run() {
43 try {
44 if("off".equals(ConfigService.getConfigRealTime(ConfigService.DYNAMIC_LOAD_MYBATIS_XML_SWITCH))) {
45
46 }else {
47 if (scanner.isChanged()) {
48 System.out.println("load mapper.xml");
49 scanner.reloadXML();
50 }
51 }
52
53 } catch (Exception e) {
54 e.printStackTrace();
55 }
56 }
57 }, 10 * 1000, 5 * 1000);
58 } catch (Exception e1) {
59 e1.printStackTrace();
60 }*/
61 }
62
63 public Scanner getScanner() {
64 return scanner;
65 }
66
67 public void setScanner(Scanner scanner) {
68 this.scanner = scanner;
69 }
70
71 @SuppressWarnings("unchecked")
72 public
73 class Scanner {
74 //此处应调整为可配置
75 private static final String XML_RESOURCE_PATTERN = "com/sdyy/**/model/*.xml";//ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + "**/*Mapper.xml";
76 private final ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
77 public Scanner() throws IOException {
78 Resource[] resources = findResource();
79 if (resources != null) {
80 for (Resource resource : resources) {
81 String key = resource.getURI().toString();
82 String value = getMd(resource);
83 mappers.put(key, value);
84 }
85 }
86 }
87 public void reloadXML() throws Exception {
88 SqlSessionFactory factory = context.getBean(SqlSessionFactory.class);
89 Configuration configuration = factory.getConfiguration();
90 removeConfig(configuration);
91 for (Resource resource : findResource()) {
92 try {
93 XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(resource.getInputStream(), configuration, resource.toString(), configuration.getSqlFragments());
94 xmlMapperBuilder.parse();
95 } finally {
96 ErrorContext.instance().reset();
97 }
98 }
99 }
100 private void removeConfig(Configuration configuration) throws Exception {
101 Class<?> classConfig = configuration.getClass();
102 clearMap(classConfig, configuration, "mappedStatements");
103 clearMap(classConfig, configuration, "caches");
104 clearMap(classConfig, configuration, "resultMaps");
105 clearMap(classConfig, configuration, "parameterMaps");
106 clearMap(classConfig, configuration, "keyGenerators");
107 clearMap(classConfig, configuration, "sqlFragments");
108 clearSet(classConfig, configuration, "loadedResources");
109 }
110 private void clearMap(Class<?> classConfig, Configuration configuration, String fieldName) throws Exception {
111 Field field = classConfig.getDeclaredField(fieldName);
112 field.setAccessible(true);
113 ((Map) field.get(configuration)).clear();
114 }
115 private void clearSet(Class<?> classConfig, Configuration configuration, String fieldName) throws Exception {
116 Field field = classConfig.getDeclaredField(fieldName);
117 field.setAccessible(true);
118 ((Set) field.get(configuration)).clear();
119 }
120 public boolean isChanged() throws IOException {
121 boolean isChanged = false;
122 for (Resource resource : findResource()) {
123 String key = resource.getURI().toString();
124 String value = getMd(resource);
125 if (!value.equals(mappers.get(key))) {
126 isChanged = true;
127 mappers.put(key, value);
128 }
129 }
130 return isChanged;
131 }
132 private Resource[] findResource() throws IOException {
133 return resourcePatternResolver.getResources(XML_RESOURCE_PATTERN);
134 }
135 private String getMd(Resource resource) throws IOException {
136 return new StringBuilder().append(resource.contentLength()).append("-").append(resource.lastModified()).toString();
137 }
138 }
139 }



【MybatisMapperLoadUtil】② (这个是根据 mybatis-config.xml所写的所有mappers的路径更新xml)

1 import java.io.IOException;
2 import java.io.InputStream;
3 import java.lang.reflect.Field;
4 import java.util.Collection;
5 import java.util.HashMap;
6 import java.util.Map;
7 import java.util.Set;
8
9 import org.apache.ibatis.binding.MapperRegistry;
10 import org.apache.ibatis.builder.xml.XMLConfigBuilder;
11 import org.apache.ibatis.builder.xml.XMLMapperBuilder;
12 import org.apache.ibatis.builder.xml.XMLMapperEntityResolver;
13 import org.apache.ibatis.exceptions.ExceptionFactory;
14 import org.apache.ibatis.executor.ErrorContext;
15 import org.apache.ibatis.io.Resources;
16 import org.apache.ibatis.mapping.MappedStatement;
17 import org.apache.ibatis.parsing.XNode;
18 import org.apache.ibatis.parsing.XPathParser;
19 import org.apache.ibatis.session.Configuration;
20 import org.apache.ibatis.session.SqlSessionFactory;
21 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
22 import org.apache.log4j.Logger;
23 import org.springframework.beans.BeansException;
24 import org.springframework.beans.factory.InitializingBean;
25 import org.springframework.context.ApplicationContext;
26 import org.springframework.context.ApplicationContextAware;
27 import org.springframework.context.ConfigurableApplicationContext;
28 import org.springframework.core.io.Resource;
29 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
30 import org.springframework.core.io.support.ResourcePatternResolver;
31
32 /**
33 * 用于重新加载Mapper的工具
34 */
35 public class MybatisMapperLoadUtil implements InitializingBean, ApplicationContextAware {
36 // 日志记录器
37 private final Logger logger = Logger.getLogger(this.getClass());
38 private final HashMap<String, String> mappers = new HashMap<String, String>();
39 private volatile ConfigurableApplicationContext context = null;
40 private volatile Scanner scanner = null;
41
42 @Override
43 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
44 this.context = (ConfigurableApplicationContext) applicationContext;
45 }
46
47 @Override
48 public void afterPropertiesSet() throws Exception {
49 setScanner(new Scanner());
50 /*try {
51
52 new Timer(true).schedule(new TimerTask() {
53 public void run() {
54 try {
55 if("off".equals(ConfigService.getConfigRealTime(ConfigService.DYNAMIC_LOAD_MYBATIS_XML_SWITCH))) {
56
57 }else {
58 if (scanner.isChanged()) {
59 System.out.println("load mapper.xml");
60 scanner.reloadXML();
61 }
62 }
63
64 } catch (Exception e) {
65 e.printStackTrace();
66 }
67 }
68 }, 10 * 1000, 5 * 1000);
69 } catch (Exception e1) {
70 e1.printStackTrace();
71 }*/
72 }
73
74 public Scanner getScanner() {
75 return scanner;
76 }
77
78 public void setScanner(Scanner scanner) {
79 this.scanner = scanner;
80 }
81
82 @SuppressWarnings("unchecked")
83 public
84 class Scanner {
85 //此处应调整为可配置
86 private static final String XML_RESOURCE_PATTERN = "**/model/*mybatis.xml";//ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + "**/*Mapper.xml";
87 private final ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
88 public Scanner() throws IOException {
89 Resource[] resources = findResource();
90 if (resources != null) {
91 for (Resource resource : resources) {
92 String key = resource.getURI().toString();
93 String value = getMd(resource);
94 mappers.put(key, value);
95 }
96 }
97 }
98 public void reloadXML() throws Exception {
99 SqlSessionFactory factory = context.getBean(SqlSessionFactory.class);
100 Configuration configuration = factory.getConfiguration();
101
102 removeConfig(configuration);
103
104
105 //获取新的mybatis-config文件配置 2016年1月5日17:49:37
106 InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
107
108 try {
109 XPathParser parser = new XPathParser(inputStream, true, null, new XMLMapperEntityResolver());
110 for (XNode child : parser.evalNode("/configuration").evalNode("mappers").getChildren()) {
111 String resourcePath = child.getStringAttribute("resource");
112 Resource resource = resourcePatternResolver.getResource(resourcePath);
113 XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(resource.getInputStream(), configuration, resource.toString(), configuration.getSqlFragments());
114 xmlMapperBuilder.parse();
115
116 }
117 } catch (Exception e) {
118 throw ExceptionFactory.wrapException("Error building SqlSession.", e);
119 } finally {
120 ErrorContext.instance().reset();
121 try {
122 inputStream.close();
123 } catch (IOException e) {
124 // Intentionally ignore. Prefer previous error.
125 }
126 }
127 }
128 private void removeConfig(Configuration configuration) throws Exception {
129 Class<?> classConfig = configuration.getClass();
130 clearMap(classConfig, configuration, "mappedStatements");
131 clearMap(classConfig, configuration, "caches");
132 clearMap(classConfig, configuration, "resultMaps");
133 clearMap(classConfig, configuration, "parameterMaps");
134 clearMap(classConfig, configuration, "keyGenerators");
135 clearMap(classConfig, configuration, "sqlFragments");
136 clearSet(classConfig, configuration, "loadedResources");
137 }
138 private void clearMap(Class<?> classConfig, Configuration configuration, String fieldName) throws Exception {
139 Field field = classConfig.getDeclaredField(fieldName);
140 field.setAccessible(true);
141 ((Map) field.get(configuration)).clear();
142 }
143 private void clearSet(Class<?> classConfig, Configuration configuration, String fieldName) throws Exception {
144 Field field = classConfig.getDeclaredField(fieldName);
145 field.setAccessible(true);
146 ((Set) field.get(configuration)).clear();
147 }
148 public boolean isChanged() throws IOException {
149 boolean isChanged = false;
150 for (Resource resource : findResource()) {
151 String key = resource.getURI().toString();
152 String value = getMd(resource);
153 if (!value.equals(mappers.get(key))) {
154 isChanged = true;
155 mappers.put(key, value);
156 }
157 }
158 return isChanged;
159 }
160 private Resource[] findResource() throws IOException {
161 return resourcePatternResolver.getResources(XML_RESOURCE_PATTERN);
162 }
163 private String getMd(Resource resource) throws IOException {
164 return new StringBuilder().append(resource.contentLength()).append("-").append(resource.lastModified()).toString();
165 }
166 }
167 }


举报

相关推荐

0 条评论