spring 整合cxf批量發佈多個接口

spring 整合webService後需要在spring-cxf中配置需要發佈的接口,配置如下:

 <bean id="DemoServiceBean"  
         class="com.app.ahnyapp.cxf.impl.DemoServiceImpl">  	
    </bean>  
   <!--  #DemoService是和你的實現類上聲明的serviceName一致  
    id 同上面你聲明的bean id  
    address 是web.xml上面配置的cxf匹配路徑之後的路徑,隨便起命,但是訪問時要一致   -->
    <jaxws:endpoint id="DemoService" implementor="#DemoServiceBean"  
        address="DemoService" />  

現在問題是,我需要提供的接口很多,而且每個接口都在不同的接口類中,那麼我的每個接口都需要配置一個bean 和endpoint,就比較麻煩,所以對這一塊進行了相應的修改,自動掃描需要發佈的接口實現類。

實現過程:掃描固定包下的以Impl結尾的實現類,把這些類在項目啓動的時候加載到webservice中的endpoint中去,把這些實現層的Impl去掉做爲接口名稱

/**
 * 
 * 此類描述的是:webservice 注入到spring容器中,掃描classPath 下面的包含impl的實現類,加載到webservice中
 * 
 * @author: yangzhen
 * @version: 2019年12月17日 下午3:14:44
 * @ClassName: CxfConfig
 * @項目: ahny
 * @包:com.app.ahnyapp.cxf.config
 */
// 註冊到spring啓動中
@Configuration
public class CxfConfig {

	private final static String classPath = "com.app.ahnyapp.cxf";
	private final static String cutString = "impl";

	@Bean(name = Bus.DEFAULT_BUS_ID)
	public SpringBus springBus() {
		return new SpringBus();
	}



	@Bean
	public Endpoint endpoint() {
		List list = new ArrayList();
		list = getImplClassPath();
		EndpointImpl endpoint = null;
		for (int i = 0; i < list.size(); i++) {
			// 根據給定的類名初始化類
			Class catClass;
			try {
				catClass = Class.forName((String) list.get(i));
				// 實例化這個類
				Object obj = catClass.newInstance();

				endpoint = new EndpointImpl(springBus(), obj);// 綁定要發佈的服務實現類

				// 截取class名稱去掉最後的impl作爲服務的名稱
				String serviceName = (String) list.get(i);
				serviceName = serviceName.substring(serviceName
						.lastIndexOf(".") + 1);
				serviceName = serviceName
						.substring(0, serviceName.length() - 4);
				endpoint.publish("/" + serviceName); // 接口訪問地址
			} catch (Exception e) {
				e.printStackTrace();
			}

		}

	 return endpoint;
	 }

	


	/**
	 * 
	 * 此方法描述的是:獲取com.app.ahnyapp.cxf 以impl爲結尾的類的路徑
	 * 
	 * @Title: getImplClassPath
	 * @author: yangzhen
	 * @return
	 * @return List 返回類型
	 * @version: 2019年12月17日 下午3:05:22
	 */
	private static List getImplClassPath() {
		List list = new ArrayList();
		Set classNames = ClassUtil.getClassSet(classPath);
		if (classNames != null) {

			for (Iterator iterator = classNames.iterator(); iterator.hasNext();) {
				String classPath = iterator.next().toString();
				String lowerCase = classPath.toLowerCase();
				if (lowerCase.contains(cutString)) {
					classPath = classPath.substring(6, classPath.length());
					list.add(classPath);
				}
			}

		}
		return list;
	}

}

ClassUtil代碼如下

package com.haozi.core.util;

import java.io.File;
import java.io.FileFilter;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

/**
 * 
 * 此類描述的是:類操作工具類
 * 
 * @author: yangzhen
 * @version: 2019年12月17日 上午11:21:33
 * @ClassName: ClassUtil
 * @項目: ahny
 * @包:com.haozi.core.util
 */
public final class ClassUtil {

	private static Logger LOGGER = Logger.getLogger(ClassUtil.class);

	/**
	 * 獲取類加載器
	 */
	public static ClassLoader getClassLoader() {
		return Thread.currentThread().getContextClassLoader();
	}

	/**
	 * 加載類
	 */
	public static Class<?> loadClass(String className, boolean isInitialized) {
		Class<?> cls;
		try {
			cls = Class.forName(className, isInitialized, getClassLoader());
		} catch (ClassNotFoundException e) {
			LOGGER.error("load class failure", e);
			throw new RuntimeException(e);
		}
		return cls;
	}

	/**
	 * 加載類(默認將初始化類)
	 */
	public static Class<?> loadClass(String className) {
		return loadClass(className, true);
	}

	/**
	 * 獲取指定包名下的所有類
	 */
	public static Set<Class<?>> getClassSet(String packageName) {
		Set<Class<?>> classSet = new HashSet<Class<?>>();
		try {
			Enumeration<URL> urls = getClassLoader().getResources(
					packageName.replace(".", "/"));
			while (urls.hasMoreElements()) {
				URL url = urls.nextElement();
				if (url != null) {
					String protocol = url.getProtocol();
					if (protocol.equals("file")) {
						String packagePath = url.getPath().replaceAll("%20",
								" ");
						addClass(classSet, packagePath, packageName);
					} else if (protocol.equals("jar")) {
						JarURLConnection jarURLConnection = (JarURLConnection) url
								.openConnection();
						if (jarURLConnection != null) {
							JarFile jarFile = jarURLConnection.getJarFile();
							if (jarFile != null) {
								Enumeration<JarEntry> jarEntries = jarFile
										.entries();
								while (jarEntries.hasMoreElements()) {
									JarEntry jarEntry = jarEntries
											.nextElement();
									String jarEntryName = jarEntry.getName();
									if (jarEntryName.endsWith(".class")) {
										String className = jarEntryName
												.substring(
														0,
														jarEntryName
																.lastIndexOf("."))
												.replaceAll("/", ".");
										doAddClass(classSet, className);
									}
								}
							}
						}
					}
				}
			}
		} catch (Exception e) {
			LOGGER.error("get class set failure", e);
			throw new RuntimeException(e);
		}
		return classSet;
	}

	private static void addClass(Set<Class<?>> classSet, String packagePath,
			String packageName) {
		File[] files = new File(packagePath).listFiles(new FileFilter() {
			public boolean accept(File file) {
				return (file.isFile() && file.getName().endsWith(".class"))
						|| file.isDirectory();
			}
		});
		for (File file : files) {
			String fileName = file.getName();
			if (file.isFile()) {
				String className = fileName.substring(0,
						fileName.lastIndexOf("."));
				if (StringUtils.isNotEmpty(packageName)) {
					className = packageName + "." + className;
				}
				doAddClass(classSet, className);
			} else {
				String subPackagePath = fileName;
				if (StringUtils.isNotEmpty(packagePath)) {
					subPackagePath = packagePath + "/" + subPackagePath;
				}
				String subPackageName = fileName;
				if (StringUtils.isNotEmpty(packageName)) {
					subPackageName = packageName + "." + subPackageName;
				}
				addClass(classSet, subPackagePath, subPackageName);
			}
		}
	}

	private static void doAddClass(Set<Class<?>> classSet, String className) {
		Class<?> cls = loadClass(className, false);
		classSet.add(cls);
	}
}


這樣spring整合的cxf基本上就不需要在cxf.xml中添加配置了,最後在webService實現層裏發現@Autowired註解注入不了其他的service,爲null,這裏改成了@Resource就能注入了成功了
最後這裏提供下spring4.2.0+cxf的3.1.18的jar 包 cxf3.1.18

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章