`

Java自动生成Spring配置文件

    博客分类:
  • Tool
 
阅读更多
使用Spring有两种方式,一种是annotation,一种是配置。
其实使用annotation是不错的选择,但是annotation分布在系统代码之中不利于管理.
所以现在流行使用最多的,还是xml方式。
但是使用Spring的xml配置实在是麻烦,而且还容易把包名,类名写错。
于是我想:"能不能自已动生成Spring的配置文件";
说明一下:我一直相信代码的自动构建比“人工敲代码”更可靠
凭着这个想法,实现如下:
package org.frame.base.unit;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import org.frame.base.web.controller.BaseController;
import org.springframework.aop.ClassFilter;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 * 自动构建bean配置文件 提供包名,自动生成该包以下的Bean配置文件内容.[包含子包]
 * 		1.	BaseController 如果为这个类的实例,自动生成parent
 *
 * @author yangchunlong.tw
 *
 */
public class GeneratorBean {

	private static final String PROTOCOL_FILE = "file";
	private static final String CLASS_FILE = ".class";
	private static final String BASE_CONTROLLER = "baseController";
	private final String packageName;
	private final ClassFilter filter;// 可以没有classFilter
	private final String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE beans PUBLIC \"-//SPRING//DTD BEAN//EN\" \" http://www.springframework.org/dtd/spring-beans.dtd \">\n";


	public GeneratorBean(String packageName) {
		this(packageName, null);
	}

	public GeneratorBean(String packageName, ClassFilter filter) {
		this.packageName = packageName;
		this.filter = filter;
	}

	/**
	 * 生成配置串
	 * @return
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public String buildSpringBean() throws IOException {
		List<Class<?>> clazzs = scannerPackage();
		StringBuffer sb = new StringBuffer(header);
		for (Class clazz : clazzs) {
			try {
				if(BaseController.class.isInstance(clazz.newInstance())){
					sb.append("	<bean class=\"").append(clazz.getName()).append("\"").append(" parent=\"").append(BASE_CONTROLLER).append("\" ")
						.append(" />").append("\n");
				}else{
					sb.append("	<bean class=\"").append(clazz.getName()).append("\"")
						.append(" />").append("\n");
				}
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
		return sb.toString();
	}

	/**
	 * 生成配置文件
	 * @throws IOException
	 */
	public void  buildSpringXML(String fileName){
		String base = System.getProperty("user.dir");
		FileOutputStream os = null;
		OutputStreamWriter writer = null;
		try {
			 os = new FileOutputStream(base+"/"+fileName);
			 writer = new OutputStreamWriter(os,Charset.forName("UTF-8"));
			 XStream xStream = new XStream(new DomDriver());// 不需要XPP3库
		     xStream.alias("beans", Beans.class);
		     xStream.alias("bean", Bean.class);
		     xStream.useAttributeFor(String.class);
		     xStream.aliasField("default-autowire", Beans.class, "default_autowire");
		     xStream.aliasField("class", Bean.class, "_class");
		     Beans beans = new Beans();
		     List<Class<?>> clazzs = scannerPackage();
		     for (Class clazz : clazzs) {
		    	 Bean bean = new Bean();
		    	 try {
					if(BaseController.class.isInstance(clazz.newInstance())){
							bean.set_class(clazz.getName());
							bean.setParent(BASE_CONTROLLER);
						}else{
							bean.set_class(clazz.getName());
						}
				} catch (InstantiationException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
				beans.addBean(bean);
		     }
		    writer.write(header);
		    xStream.toXML(beans, writer);
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
//			IOUtils.copy(reader, writer);
			 try {
			    os.close();
				writer.close();
			 } catch (IOException e) {
	                e.printStackTrace();
	         }
		}
	}

	/**
	 * 遍历文件夹下的所有类
	 *
	 * @param packageName
	 * @return
	 * @throws IOException
	 */
	public List<Class<?>> scannerPackage() throws IOException {
		List<Class<?>> list = new ArrayList<Class<?>>();
		Enumeration<URL> en = getClass().getClassLoader().getResources(
				dotToPath(packageName));
		while (en.hasMoreElements()) {
			URL url = en.nextElement();
			if (PROTOCOL_FILE.equals(url.getProtocol())) {
				EncodingUtils parse = new EncodingUtils();
				String fileName = parse.decodeURL(url.getFile(), "UTF-8");
				File root = new File(fileName);
				findInDirectory(list, root, root, packageName);
			}
		}
		return list;
	}

	private void findInDirectory(List<Class<?>> results, File rootDir,
			File dir, String packageName) {
		File[] files = dir.listFiles();
		String rootPath = rootDir.getPath();
		for (File file : files) {
			if (file.isFile()) {
				String classFileName = file.getPath();
				if (classFileName.endsWith(CLASS_FILE)) {
					String className = classFileName.substring(rootPath
							.length()
							- packageName.length(), classFileName.length()
							- CLASS_FILE.length());
					add(results, pathToDot(className));
				}
			} else if (file.isDirectory()) {
				findInDirectory(results, rootDir, file, packageName);
			}
		}
	}

	/**
	 * 添加 某个类名到某架包中 此类必须匹配ClassFilter.[]
	 *
	 * @param results
	 * @param className
	 */
	private void add(List<Class<?>> results, String className) {
		Class<?> clazz = null;
		try {
			clazz = Class.forName(className);
		} catch (ClassNotFoundException e) {
			// 架包中会有些类会加载不到.
			System.out.println("加载类失败:" + className);
			return;
		}
		if (filter == null || filter.matches(clazz))
			results.add(clazz);
	}

	/**
	 * 转包名为路径[. ==> /]
	 *
	 * @param s
	 * @return
	 */
	private String dotToPath(String s) {
		return s.replace('.', '/');
	}

	/**
	 * 转路径为包名[/ ==> .]/[\\ ==> .]
	 *
	 * @param s
	 * @return
	 */
	private String pathToDot(String s) {
		return s.replace('/', '.').replace('\\', '.');
	}

}



以上是实现代码,主要是使用字符串拼凑来实现xml的输出和xstream的面向对象方式来序列化XML,我还是比较喜欢xstream,还可以把xml反序列化为Java对象.

测试代码如下:
package com.frame.base.unit;

import java.io.IOException;

import org.frame.base.unit.GeneratorBean;
import org.springframework.aop.ClassFilter;
import org.springframework.web.servlet.mvc.Controller;


/**
 * 可以自动生成Controler的实例才生成配置文件
 * @author yangchunlong.tw
 *
 */
public class TestGeneratorBean {
	/**
	 * 不需要自动生成的Controller
	 */
	static String[] exps = new String[]{
								"handing.beanName.IndexSpringController"
							   };

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub

		GeneratorBean gg = new GeneratorBean("handing",new ClassFilter(){
			@Override
			public boolean matches(Class clazz) {
				try {
					if(Controller.class.isInstance(clazz.newInstance())){
							for(String exp:exps){
								if(exp.equals(clazz.getName())){
									return false;
								}
							}
							return true;
						}else{
							return false;
						}
				} catch (InstantiationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return false;
			}
		});
		System.out.println(gg.buildSpringBean());
		System.out.println(System.getProperty("user.dir"));
		gg.buildSpringXML("beans2.xml");
	}

}



这里定义了自动构建的过程,比如,我可以把包名handing以下的类生成bean,
这里定义了规则;
        1. 此类必须为Controller的实例类。
         2. 此类不在exps 的列表里面
可能有些类不需要生成配置,在这里可以配置。
当然规则是自定义的,我在自动构建的代码里面,也使用了规则,比如实例为"BaseController"的生成parent参数,如果不是的,只需要生成普通的bean.
以下是xstream的实例类:
package org.frame.base.unit;

import java.util.ArrayList;
import java.util.List;

/**
 * <beans default-autowire=\"byName\">
 * 	...
 *  <bean .../>
 * </beans>
 * @author yangchunlong.tw
 *
 */
public class Beans {
	/**
	 * 自动构建方式:默认byName[default_autowire == > default-autowire]
	 */
	private String default_autowire = "byName";

	/**
	 * Spring的bean.
	 */
	List<Bean> beans = new ArrayList<Bean>();

	public String getDefault_autowire() {
		return default_autowire;
	}
	public void setDefault_autowire(String default_autowire) {
		this.default_autowire = default_autowire;
	}
	public List<Bean> getBeans() {
		return beans;
	}
	public void setBeans(List<Bean> beans) {
		this.beans = beans;
	}
	public void addBean(Bean bean){
		beans.add(bean);
	}
}


package org.frame.base.unit;

public class Bean {

	/**
	 * bean_类包名[_class == > class]
	 */
	private String _class;

	/**
	 * bean_父bean
	 */
	private String parent;

	public String get_class() {
		return _class;
	}

	public void set_class(String _class) {
		this._class = _class;
	}

	public String getParent() {
		return parent;
	}

	public void setParent(String parent) {
		this.parent = parent;
	}

}


使用xstream扩展起来比较方便,比如,如果你使用的是CustomSpring扩展的Application.那么使用自己扩展的属性将是相当犀利的哦。
最后输出xml的结构如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" " http://www.springframework.org/dtd/spring-beans.dtd ">
<beans default-autowire="byName">
    <bean class="handing.beanName.screen.home.HomeAuto"/>
    <bean class="handing.beanName.screen.home.AdminAuto" parent="baseController"/>
    <bean class="handing.beanName.screen.IndexAuto"/>
    <bean class="handing.beanName.IndexController"/>
    <bean class="handing.beanName.IndexAdminController"/>
</beans>

这可是相当标准的xml哦,直接复制到运行目标就可以了.
0
1
分享到:
评论
7 楼 a123159521 2012-05-18  
flighting 写道
楼主麻烦问下这个类BaseController怎么实现的?

只是一个普通的Java类而已。 Spring的parent还是比较好用的。
6 楼 flighting 2012-05-17  
楼主麻烦问下这个类BaseController怎么实现的?
5 楼 a123159521 2011-11-01  
kobbyla 写道
读您的博客,收益匪浅...值得学习

好久没来更新了,呵呵。
4 楼 kobbyla 2011-10-24  
读您的博客,收益匪浅...值得学习
3 楼 a123159521 2011-09-16  
SINCE1978 写道
楼主麻烦问下这个类BaseController怎么实现的?

BaseController是自定义的一个基类
2 楼 SINCE1978 2011-08-16  
楼主麻烦问下这个类BaseController怎么实现的?
1 楼 SINCE1978 2011-08-15  
你好,打扰一下,我正需要java自动生成spring文件所以想参考一下你代码,但是发现有一些类找不到,你提供一下吗,我QQ:350619968 谢谢!

相关推荐

    AutoCode_SSHDemo_Setup自动生成HIBERNATE 配置文件 JAVA代码自动生成

    标题中的"AutoCode_SSHDemo_Setup自动生成HIBERNATE 配置文件 JAVA代码自动生成"表明这是一个关于自动化代码生成的工具,主要用于简化Hibernate配置文件和Java代码的编写过程。SSH在这里指的是Spring、Struts和...

    auto-spring:自动生成spring配置文件`spring.factories`

    "auto-spring"项目看起来是一个工具或库,旨在自动化生成Spring框架的配置文件`spring.factories`。`spring.factories`文件在Spring Boot中扮演着重要的角色,它是Spring Boot启动和加载自动配置、starter组件的关键...

    使用xDoclet自动生成Spring的bean的配置文件

    在IT行业中,自动化是提升效率的关键之一,而xDoclet正是这样一个工具,它能帮助我们自动地生成Spring框架中的bean配置文件。这篇文章将深入探讨如何使用xDoclet以及它在Spring环境中的应用。 首先,xDoclet是一款...

    SSM框架自动生成配置文件

    这个“SSM框架自动生成配置文件”文件主要关注的是如何简化SSM集成过程中的配置工作,特别是通过MyBatis Generator来自动化生成数据库映射文件和实体类,从而提高开发效率。 Spring作为核心容器,负责管理对象...

    Spring Cloud+mybatise + mysql 自动生成代码工具

    "Spring Cloud+mybatise + mysql 自动化代码生成工具"是这样一种解决方案,它能够帮助开发者按照预设规则自动生成常见的Controller、Service以及mapping配置文件等基础类,从而显著提升开发效率。 首先,我们来详细...

    使用Java自动生成Java类和XML文件

    在Java开发过程中,有时我们需要快速生成大量的Java类或者XML配置文件,这通常是为了构建数据模型、映射文件或实现某种自动化任务。为了提高效率,开发者会利用代码生成工具,例如MyBatis的MyBatis Generator或者...

    JavaBean实体类 配置文件 代码一键自动生成工具

    代码一键自动生成工具 可生成Action、JavaBean实体类、Dao及实现类、service及实现类、spring.xml、struts.xml、mybatis.xml *该工具目前支持3种数据源的生成方式,分别是:JDBC、.table、PDM *JDBC:选择JDBC是只...

    java代码自动生成器 ,通过页面生成

    集成Spring Boot意味着代码生成器可以创建出符合Spring Boot风格的项目结构,包括配置文件、启动类、MVC控制器、Service层以及Repository层,使得生成的代码能够无缝融入Spring Boot环境,便于后期开发和维护。...

    springboot+mybatis(mybatis dao与xml文件自动生成)

    在Spring Boot和MyBatis框架集成的开发过程中,自动化生成DAO层接口与对应的XML配置文件可以极大地提高开发效率。下面将详细介绍如何实现这一功能,并深入探讨相关知识点。 首先,Spring Boot是一个快速开发框架,...

    java文件自动生成模板

    总之,Java文件自动生成模板是一个实用的开发辅助工具,通过配置和模板引擎,可以实现快速生成符合规范的Java代码,提高开发效率,降低错误率。在这个项目中,用户只需运行`AutoMain`,就能体验到自动生成代码的便利...

    java 代码自动生成

    使用该工具时,开发者需要配置数据库连接信息,选择需要生成代码的表,工具就会自动生成相应的Java源码和XML配置文件。这极大地提高了开发效率,减少了重复劳动,让开发者可以更专注于业务逻辑的实现,而不是基础...

    java插件配置代码生成器

    3. **代码生成**:生成符合Java语法的源代码文件,这可能包括类、接口、方法等,以及与之相关的XML配置文件,如Spring的bean定义。 4. **文件写入**:将生成的代码保存到指定的目录,以便在项目中使用。 5. **错误...

    自动生成springMvc和mybatis映射文件

    5. MyBatis Generator读取配置文件,连接数据库,然后根据配置生成相应的Java源代码和Mapper XML文件。 通过这个过程,我们可以快速地构建起SpringMVC和MyBatis的项目结构,极大地提高了开发效率。在实际应用中,...

    基于Spring MVC与Apache Dbutils整合的图形化模板定制一键生成代码及Spring配置文件设计源码

    该项目是一款基于Spring MVC框架和Apache Dbutils集成的图形化模板定制工具,旨在实现一键化自动生成Model、DAO、Service代码及Spring Web配置文件。该工具采用Freemarker模板语言进行代码生成,支持事务控制,并...

    基于Java的mica-auto注解自动生成Java SPI和Spring Boot配置设计源码

    mica-auto是一个使用注解自动生成Java SPI和Spring Boot配置的工具,旨在简化开发过程中的配置工作,提高开发效率。该项目还提供了文档和示例代码,帮助开发者快速上手。记得在右上角点个star关注更新!

    最新版java代码生成器基于springMvc+mysql 后台功能一键生成

    最新版java代码生成器基于springMvc+mysql 后台功能一键生成 压缩包里的jdk文件目录 请自行下载jdk1.8.0_45版本并覆盖进去 没有jdk是运行不起来的 也可以下载其他jdk版本 但是jdk1.8.0_45这个文件目录名称不要更改 ...

    Spring 配置文件 和详细笔记

    Spring配置文件是Spring框架的核心组成部分,用于定义bean的创建、装配以及它们之间的关系。在本文中,我们将深入探讨Spring配置文件的相关知识点,以及如何有效地使用它们。 1. **XML配置文件** - **基本结构**:...

    java代码自动生成工具

    5. **Maven/Gradle集成**:大多数现代Java项目使用构建工具如Maven或Gradle,代码生成工具会将生成的代码正确地整合到项目的目录结构中,并更新相应的配置文件。 6. **国际化支持**:对于多语言应用,工具可以帮助...

Global site tag (gtag.js) - Google Analytics