遗忘海岸

江湖程序员 -Feiph(LM战士)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

cxf的一些使用说明

复制代码
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.cxf.transport.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Enumeration;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.common.util.ReflectionUtil;
import org.apache.cxf.helpers.CastUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.context.support.XmlWebApplicationContext;

public class CXFServlet extends CXFNonSpringServlet
    implements ApplicationListener<ContextRefreshedEvent> {
    private static final long serialVersionUID = -5922443981969455305L;
    private boolean busCreated;
    private XmlWebApplicationContext createdContext; 
    
    public CXFServlet() {
    }

    @Override
    protected void loadBus(ServletConfig sc) {
        ApplicationContext wac = WebApplicationContextUtils.
            getWebApplicationContext(sc.getServletContext());
        
        if (wac instanceof AbstractApplicationContext) {
            addListener((AbstractApplicationContext)wac);
        }
        
        String configLocation = sc.getInitParameter("config-location");
        if (configLocation == null) {
            try {
                InputStream is = sc.getServletContext().getResourceAsStream("/WEB-INF/cxf-servlet.xml");
                if (is != null && is.available() > 0) {
                    is.close();
                    configLocation = "/WEB-INF/cxf-servlet.xml";
                }
            } catch (Exception ex) {
                //ignore
            }
        }
        if (configLocation != null) {
            wac = createSpringContext(wac, sc.getServletContext(), configLocation);
        }
        if (wac != null) {
            setBus((Bus)wac.getBean("cxf", Bus.class));
        } else {
            busCreated = true;
            setBus(BusFactory.newInstance().createBus());
        }
    }

    protected void addListener(AbstractApplicationContext wac) {
        try {
            //spring 2 vs spring 3 return type is different
            Method m = wac.getClass().getMethod("getApplicationListeners");
            Collection<Object> c = CastUtils.cast((Collection<?>)ReflectionUtil
                                                      .setAccessible(m).invoke(wac));
            c.add(this);
        } catch (Throwable t) {
            //ignore.
        }
    }

    /**
     * Try to create a spring application context from the config location.
     * Will first try to resolve the location using the servlet context.
     * If that does not work then the location is given as is to spring
     * 
     * @param ctx
     * @param sc
     * @param configLocation
     * @return
     */
    private ApplicationContext createSpringContext(ApplicationContext ctx,
                                                   final ServletContext sc,
                                                   String location) {
        XmlWebApplicationContext ctx2 = new XmlWebApplicationContext();
        createdContext = ctx2;
        ctx2.setServletConfig(new ServletConfig() {
            public String getServletName() {
                return "CXF";
            }
            public ServletContext getServletContext() {
                return sc;
            }
            public String getInitParameter(String name) {
                return sc.getInitParameter(name);
            }
            public Enumeration<String> getInitParameterNames() {
                return sc.getInitParameterNames();
            }
        });
        Resource r = ctx2.getResource(location);
        try {
            InputStream in = r.getInputStream();
            in.close();
        } catch (IOException e) {
            //ignore
            r = ctx2.getResource("classpath:" + location);
            try {
                r.getInputStream().close();
            } catch (IOException e2) {
                //ignore
                r = null;
            }
        }
        try {
            if (r != null) {
                location = r.getURL().toExternalForm();
            }
        } catch (IOException e) {
            //ignore
        }        
        if (ctx != null) {
            ctx2.setParent(ctx);
            String names[] = ctx.getBeanNamesForType(Bus.class);
            if (names == null || names.length == 0) {
                ctx2.setConfigLocations(new String[] {"classpath:/META-INF/cxf/cxf.xml",
                                                      location});                
            } else {
                ctx2.setConfigLocations(new String[] {location});                                
            }
        } else {
            ctx2.setConfigLocations(new String[] {"classpath:/META-INF/cxf/cxf.xml",
                                                  location});
            createdContext = ctx2;
        }
        ctx2.refresh();
        return ctx2;
    }
    public void destroyBus() {
        if (busCreated) {
            //if we created the Bus, we need to destroy it.  Otherwise, spring will handleit.
            getBus().shutdown(true);
            setBus(null);
        }
        if (createdContext != null) {
            createdContext.close();
        }
    }

    public void onApplicationEvent(ContextRefreshedEvent event) {
        destroy();
        setBus(null);
        try {
            init(getServletConfig());
        } catch (ServletException e) {
            throw new RuntimeException("Unable to reinitialize the CXFServlet", e);
        }
    }

}
View Code
复制代码

如果存在Web-INF/cxf-servlet.xml,或者在web.xml中配置的cxf Servlet节按中提供了config-location,那么cxf会自己创建一个spring容器,如果在web.xml中同时也使用spring的监听器创建容器

复制代码
 <context-param>
  <param-name>contextConfigLocation</param-name> 
  <param-value>classpath*:conf/cxf-servlet.xml</param-value> 
  </context-param> 
 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
  </listener>
View Code
复制代码

那么cxf容器会作为子容器,就是系统中有2个spring容器。
cxf自己创建容器时会加载classpath:/META-INF/cxf/cxf.xml这个就中的bug,如果系统只建立一个spring容器(Web-INF/下以及cxfServlet中不提供配置),那么需要自己在spring配置xml文件中通过资源导入classpath:/META-INF/cxf/cxf.xml 加载,或者将该配置放在web.xml的context-param 中

posted on   遗忘海岸  阅读(1755)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
历史上的今天:
2008-07-18 C#中的位操作
点击右上角即可分享
微信分享提示