S2S3H4框架深度集成搭建(1) XmlConfigurationProvider的hashcode的问题

 

最近一直在编写基于IOC与AOP的web开发框架,有点模仿spring的意思。IOC部分已经差很少了,正在编写persistence部分。目前所在的公司,初来乍到,并且公司软件方面之前没有积累,没有能直接使用的开发框架,但是如今项目状况有变,可能留给我本身编写框架的时间不是太够,为了以防万一,先来套Struts2,spring3,hibernate的整合框架用用,因而开始抽时间搭建。网上查了一些搭建配置的文章,可是都是简单的拼凑在一块儿就完事了,没有深度的集成。 下面就将我在集成的过程当中的一些关键的问题的解决,介绍一下。web

Struts2 在集成的时候,配置文件大可能是放置在src的根目录下就完了。这样很简单。可是没法按照本身工程的结构,进行设计调整。并且也违反了我我的本身多年的习惯。因此第一步将struts的配置放到webapp(上下文)下面的config目录里。web.xml进行以下配置。spring

  
  
  
  
  1. <filter> 
  2.         <filter-name>struts2</filter-name> 
  3.         <filter-class>com.xk.commons.config.GeneralConfigFilter</filter-class> 
  4.         <init-param> 
  5.         <param-name>configProviders</param-name> 
  6.         <param-value>com.xk.commons.config.Struts2ConfigurationProvider</param-value> 
  7.        </init-param> 
  8.     </filter> 
  9.     <filter-mapping> 
  10.         <filter-name>struts2</filter-name> 
  11.         <url-pattern>/*</url-pattern> 
  12.     </filter-mapping> 

 Struts2ConfigurationProvider 这个类是继承了StrutsXmlConfigurationProvider,顾名思义,此类是用来提供xml格式的配置用的。查看类的各类方法,我的理解,只要实现了类的getConfigurationUrls方法,返回的是你本身的配置文件的url就可以修改默认配置了。因而实现代码以下:app

  
  
  
  
  1. public class Struts2ConfigurationProvider extends StrutsXmlConfigurationProvider  
  2. {  
  3.     private static final String CONFIG_FILE = "struts.xml";  
  4.       
  5.     private static Logger logger = LoggerFactory.getLogger(Struts2ConfigurationProvider.class);  
  6.       
  7.     public Struts2ConfigurationProvider()  
  8.     {  
  9.         this(false);  
  10.     }  
  11.  
  12.     public Struts2ConfigurationProvider(boolean errorIfMissing)  
  13.     {  
  14.         super(CONFIG_FILE, errorIfMissing, null);  
  15.     }  
  16.  
  17.     @Override 
  18.     protected Iterator<URL> getConfigurationUrls(String fileName) throws IOException  
  19.     {  
  20.         logger.info("get struts config file : " + fileName);  
  21.         return PathUtils.getStrutsConfigIterator(fileName);  
  22.     }  

 

 

编写这个类的时候有点问题,在这里提一下,若是不提供默认无参构造器,在启动工程的时候会报错误, 框架

  其实这个错误发生的缘由就是在实例化这个类的时候,找不到无参构造器。一样方式,在工程外测试用例测试不会出这样的问题,仅限于struts2工程内部,不太明白为何,没找到缘由,总之,将无参构造器加上,问题解决。 可是工程启动后,好像不管如何加载不到我本身的配置。因而乎仔细读源码,发现Dispatcher类中的init_CustomConfigurationProviders方法是装载加载自定义配置的地方,其实看上面那个错误信息也大概知道地方了。发现虽然本身的Provider类是被实例化了,可是没有被被加到ConfigurationManager中,再进一步查看,发现ConfigurationManager中的CopyOnWriteArrayList中已经存在要加入的对象了,由于加入的时候会经过实例的equals进行比较。查看相同的对象,发现一个是XmlConfigurationProvider,一个是我本身定义的Struts2ConfigurationProvider,晕了,明明是两个不一样的类实例化出的对象,怎么就能equals为true呢? 想了办法,忽然茅塞顿开,若是两个不一样的类的实例比较结果是一同样的,那么只有一种可能,就是hashcode方法被重写了。由于equals比较的就是两个实例的hashcode,没错,查看XmlConfigurationProvider的方法,其中果真有hashcode方法,而方法实现又极其简单。
  
  
  
  
  1. @Override 
  2.    public int hashCode() {  
  3.        return ((configFileName != null) ? configFileName.hashCode() : 0);  
  4.    } 

看吧,只要你经过参数传递的配置文件名与struts2中默认的名字是同样的,那么hashcode就是同样的。,虽然不知道struts的开发者这样设计的目的,可是确定是有缘由的,也罢,将我本身定义的provider中的struts配置文件名字改了一下,既然自定义吗,那配置文件名称也要自定义哦。 一些都ok了, 在配置里写个简单的Action,测试经过。webapp

相关文章
相关标签/搜索