zoukankan      html  css  js  c++  java
  • 在Tomcat的多个WAR之间共享Spring

    由于非技术原因,公司的专门成立的支付部,招一批Java程序员,做了支付系统;又由于非技术原因,两个月内,这个部门从领导到程序员全走光了。然后这个支付系统就移交给我们这帮受苦受难的兄弟们维护了。在看他们代码的时候发现了很有趣的东西,就是在tomcat内共享Spring context。

        <Resource auth="Container" 
           contextConfigLocation
    ="/com/test/application-context.xml" 
           factory
    ="com.test.TomcatWebApplicationContextResourceFactory" 
           name
    ="bean/RootApplicationContextFactory" 
           type
    ="org.springframework.context.ApplicationContext"/>

    上面这段配置的意思就是,当有人通过jndi名称”bean/RootApplicationContextFactory”来查找对象时,容器就新建一个TomcatWebApplicationContextResourceFactory类实例,并调用它的getObjectInstance方法来获得资源对象。这个工厂类要是想javax.naming.spi.ObjectFactory接口。代码如下:

    package com.test;

    import java.util.Hashtable;

    import javax.naming.Context;
    import javax.naming.Name;
    import javax.naming.RefAddr;
    import javax.naming.Reference;
    import javax.naming.spi.ObjectFactory;

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class TomcatWebApplicationContextResourceFactory implements
            ObjectFactory {
        
    private static final String PARAM = "contextConfigLocation";
            
    private static final String DEFAULT = "application-context.xml";

        
    private static ApplicationContext context; //被共享的spring上下文

        
    private void init(String confFile) {
            context 
    = new ClassPathXmlApplicationContext(confFile);
        }

        
    public Object getObjectInstance(Object obj, 
                            Name name, Context nameCtx,
                Hashtable
    <??> environment) throws Exception {
            
    if (null == context) {
                
    // Customize the bean properties from our attributes
                Reference ref = (Reference) obj;

                            
    //从xml配置文件里取得contextConfigLocation元素的值
                RefAddr addr = ref.get(PARAM); 

                
    if (null != addr) {
                    String value 
    = (String) addr.getContent();
                    init(value);
                } 
    else {
                    init(DEFAULT);
                }
            }
            
    return context;
        }
    }

    1.2 在web应用中引用上面定义的资源
    修改tomcat/conf/web.xml,添加以下的内容,这样在这个tomcat下的所有的web应用就都可以访问共享的spring上下文了。

        <resource-env-ref>
            
    <description>Object factory for Root applicationcontext</description>
            
    <resource-env-ref-name> bean/RootApplicationContextFactory 
            
    </resource-env-ref-name>
            
    <resource-env-ref-type> org.springframework.context.ApplicationContext 
            
    </resource-env-ref-type>
        
    </resource-env-ref>

    1.3 加入依赖的包
    从第一步可以看出,tomcat容器需要访问spring的一些类,需要初始化上下文,所以要把初始化上下文时用到的类共享给tomcat。最简单的方法是把所有相关的类和jar包复制到tomcat/lib目录。还可以修改catalina.properties实现,如下:

    shared.loader=/usr/local/jars/*.jar

    上面的代码让tomcat载入自定目录里面所有的jar文件。

    2 我的看法
    一个庞大的spring上下文是要占用很多内存的,所有应用共享一个上下文,而不是每个web应用一份,就可以节省不少的内存。但是由此却带来了部署和配置的麻烦。如果有人利用这种机制,让多个web应用通过共享spring bean来实现一些奇怪的功能,结果导致这些应用间相互耦合,那么以后想拆分开也不容易了。总体来说,我不喜欢这样方案,但是如果真的很穷很缺内存的话,这也不失一个好方法。

  • 相关阅读:
    《面向对象编程》c++ primer 第15章
    extern的作用(综合网络)
    C程序内存区域分配(5个段作用)
    鼓舞自己的名言
    快速指数算法 和 求逆元算法
    HP Xeon 55xx上GPU的带宽问题
    Ubuntu12.04 安装ibusfbterm0.9.1
    Win7下读写Ext2/Ext3/Ext4文件系统
    fbv安装 为console添加背景图片
    CentOS6/7安装fcitx4.2.5
  • 原文地址:https://www.cnblogs.com/jifeng/p/2057537.html
Copyright © 2011-2022 走看看