为了这个功能提了很多问题都没能得到解答,最后终于自己搞定了,现在把大体步骤总结下,供大家参考指正

分三种情况:
(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总是无故消失,不知道为什么


45度仰望的压顶砖
456 声望32 粉丝

代码要优雅