为了这个功能提了很多问题都没能得到解答,最后终于自己搞定了,现在把大体步骤总结下,供大家参考指正
分三种情况:
(1)没有配置spring自动扫描
(2)2.5.*版本的spring
(3)3.*版本的spring
下面的内容只写了3.*spring版本的情况
先将class文件加密
然后写个解密的类加载器,继承自webappclassloader(项目需要引入catalina.jar,这个包位于tomcat的lib目录下),并配置到tomcat中去
tomcat中类加载器分为多层:
Bootstrap
|
System
|
Common
/ \
Webapp1 Webapp2 ...
添加自定义类加载器的时候只需要继承webappclassloader就好了。
然后将编译好的class文件复制到{$Catalina_home}lib中去,这里要注意,如果包名为A.B,那么要在lib中新建这两个目录,也就是说...libABMywebappclassloader.class
lib包有commonclassloader加载,一般只用于加载Tomcat发布的标准jar包,其他的第三方jar包可以在catalina.properties中配置shared.loader,这里由于偷懒就直接放在lib下了,假装自己写了个第三方库。
-----然后配置<context.../>元素
根据官方文档,有多个地方配置。
一般来说会在项目中的META-INF中添加一个context.xml,里面配置:
<context>
<Loader loaderClass="a.b.common.classloader.MyClassLoader" />
</context>
这个配置文件在部署时,会被复制到{$Catalina_home}confCatalinalocalhost中去,并被重新命名为:项目名.xml。
由于使用的项目中配置了
<Loader className="org.apache.catalina.loader.VirtualWebappLoader" virtualClasspath="../aaaa/*.jar"/>
来加载第三方库,配置了我自定义加载器后,"../aaaa/*.jar" 这些jar包都无法加载了。
目前我的解决办法是注释掉
<!--<Loader className="org.apache.catalina.loader.VirtualWebappLoader" virtualClasspath="../aaaa/*.jar"/>-->
然后在mywebappclassloader中使用addRepository()方法添加jar路径(仓库),代码如下:
File jarDir=new File("E:\\front_tc\\aaaa");
if(jarDir.isDirectory()){
File[] jarFiles=jarDir.listFiles(new JarFileNameFilter());
for(File jarFile:jarFiles){
try {
addRepository(jarFile.toURI().toURL().toString());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
PS:
出自How Tomcat Works
最后在SSH框架下,由于在spring.xml中配置了自动扫描
<context:component-scan base-package="a.b" />
所以a.b包下的类都会被spring自动加载
而spring自动加载时使用的类是SimpleMetadataReader
,所以要改写他用于加载的类SimpleMetadataReader
这个类是spring核心包org.springframework.core-3.0.2.RELEASE.jar
中的,我们不需要解压这个包然后替换SimpleMetadataReader.class这么麻烦,只需要在项目中建一个同名的类即可,部署到tomcat后会覆盖掉spring中的类。
建立org.springframework.core.type.classreading
包,然后建一个SimpleMetadataReader
类。随便去哪下spring的源码,然后复制过来改一下即可
写在最后:
对于要部署在linux的同学,记得把分隔符换成 System.getProperty("file.separator")。
我往开发机上打加密补丁的时候,web.xml总是无故消失,不知道为什么
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。