为了这个功能提了很多问题都没能得到解答,最后终于自己搞定了,现在把大体步骤总结下,供大家参考指正
分三种情况:
(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.classlib包有commonclassloader加载,一般只用于加载Tomcat发布的标准jar包,其他的第三方jar包可以在catalina.properties中配置shared.loader,这里由于偷懒就直接放在lib下了,假装自己写了个第三方库。-----然后配置<context.../>元素
根据官方文档,有多个地方配置。一般来说会在项目中的META-INF中添加一个context.xml,里面配置:这个配置文件在部署时,会被复制到{$Catalina_home}confCatalinalocalhost中去,并被重新命名为:项目名.xml。
由于使用的项目中配置了
来加载第三方库,配置了我自定义加载器后,"../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中配置了自动扫描
所以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总是无故消失,不知道为什么