`
userya
  • 浏览: 8154 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

零配置Service

阅读更多
1.不使用 Annotation
2.前提:约定大于配置, Service配置有规则可循
3.实现方式:
在Spring初始化时生成Service XML 配置文件,加载到初始化过程中
4.代码
1.MyXmlWebApplicationContext.java
/**
 * 
 */
package service.utils;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.util.xml.DomUtils;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * @author yangjk
 * @since 2009-9-13
 */
public class MyXmlWebApplicationContext extends XmlWebApplicationContext {

	private static Log LOG = LogFactory.getLog(MyXmlWebApplicationContext.class);

	private Properties getProperties() {
		try {
			return PropertiesLoaderUtils.loadAllProperties("config.properties");
		} catch (IOException e) {
			LOG.error("读取config.properties失败.");
			throw new RuntimeException(e);
		}
	}
	
	public byte[] getGenServiceInputStream() {
		Properties prop = getProperties();
		String path = prop.getProperty("service.path");
		String pkg = prop.getProperty("service.package");
		try {
			File file = ResourceUtils.getFile("classpath:" + path);
			Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
			List list = DomUtils.getChildElementsByTagName(doc.getDocumentElement(), "bean");
			Map map = new HashMap();
			for (int i = 0; i < list.size(); i++) {
				Element ele = (Element) list.get(i);
				map.put(ele.getAttribute("id"), ele.getAttribute("class"));
			}
			Map genMap = this.getPackageService(pkg);
			for (Iterator iterator = genMap.entrySet().iterator(); iterator.hasNext();) {
				Map.Entry entry = (Map.Entry) iterator.next();
				String id = (String)entry.getKey();
				String clazz = (String)entry.getValue();
				if(map.get(id) == null) {
					Element comm = doc.createElement("bean");
					comm.setAttribute("id", id);
					comm.setAttribute("class", clazz);
					doc.getDocumentElement().appendChild(comm);
					if (LOG.isDebugEnabled()) {
						LOG.info("Service Gen XML :" + id +" -> " + clazz);
					}
				}
			}
			DOMSource ds = new DOMSource(doc);
			Transformer transformer = TransformerFactory.newInstance().newTransformer();
			StringWriter writer = new StringWriter();
			Result result = new StreamResult(writer);
			transformer.transform(ds, result);
			return writer.toString().getBytes();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null ; 
	}

	private static final String RESOURCE_PATTERN = "**/*.class";

	private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();

	public Map getPackageService(String pkg) {
		Map map = new HashMap();
		
		String[] pkgs = pkg.split(",");
		try {
			for (int i = 0; i < pkgs.length; i++) {
				String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
						+ ClassUtils.convertClassNameToResourcePath(pkgs[i])
						+ RESOURCE_PATTERN;
				Resource[] resources;
				resources = this.resourcePatternResolver.getResources(pattern);
				MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);
				for (Resource resource : resources) {
					if (resource.isReadable()) {
						MetadataReader reader = readerFactory.getMetadataReader(resource);
						String className = reader.getClassMetadata().getClassName();
						String beanId = getBeanId(className);
						if (beanId != null) {
							map.put(beanId, className);
						}
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(
					"Failed to scan classpath for unlisted classes", e);
		}
		return map;
	}

	//约定
	private String getBeanId(String className) {
		if(StringUtils.isNotBlank(className) && className.indexOf('$') == -1) {
			String simpleName = StringUtils.substringAfterLast(className, ".");
			if(simpleName.endsWith("Impl")) {
				simpleName = simpleName.substring(0, simpleName.length()-"Impl".length());
			}
			simpleName = WordUtils.uncapitalize(simpleName);
			return simpleName ; 
		}
		return null ; 
	}
	
	protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
		Resource resource2 = new ByteArrayResource(this.getGenServiceInputStream());
		reader.loadBeanDefinitions(resource2);
	}
}


2.config.properties
#spring service xml path
service.path=conf/service.xml
#spring service package
service.package=service.impl

3.service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<!-- add your service here -->
</beans>

4.web.xml
		<context-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>
					 /WEB-INF/classes/conf/dataAccessContext-local.xml 
					 /WEB-INF/classes/conf/applicationContext.xml
					 /WEB-INF/classes/conf/controller.xml
			</param-value>
		</context-param>
		<context-param>
			<param-name>contextClass</param-name>
			<param-value>service.utils.MyXmlWebApplicationContext</param-value>
		</context-param>
		

5.按照规则可以随意扩展
分享到:
评论
11 楼 liuxiang00435057 2012-09-05  
能把工程项目共享出来就更好了,嘿嘿
10 楼 Angel_Night 2010-04-17  
代码还没认真看

这种方式挺喜欢的 不知有何潜在风险吗?

关注
9 楼 xzcgeorge 2010-04-17  
扩展的思路不错!
8 楼 userya 2009-09-27  
raymond2006k 写道
支持楼主的 service 零配置方案,可节省大量配置,维护工作 。 现在敏捷设计都趋向 约定大于配置 (CBC).

到处写 Annotation ,本质还是一种配置,而且分散到了类中,这种用法我一直觉得很恶心,对于大型系统,维护难度非常大,很不明智。

“语言不可能太智能”,这句话没错,所以,在包,类命名上尽量遵循 CBC 原则,以减少无聊的机械劳动。

其实这是为了偶的原始需求, 懒...
7 楼 raymond2006k 2009-09-27  
支持楼主的 service 零配置方案,可节省大量配置,维护工作 。 现在敏捷设计都趋向 约定大于配置 (CBC).

到处写 Annotation ,本质还是一种配置,而且分散到了类中,这种用法我一直觉得很恶心,对于大型系统,维护难度非常大,很不明智。

“语言不可能太智能”,这句话没错,所以,在包,类命名上尽量遵循 CBC 原则,以减少无聊的机械劳动。
6 楼 userya 2009-09-23  
  各有所好么.
5 楼 bjsq618 2009-09-23  
还是应用annotation的方式比较好,语言不可能太智能
4 楼 userya 2009-09-18  
satanest 写道
何苦咧~~~

yy 呀.
3 楼 satanest 2009-09-17  
何苦咧~~~
2 楼 userya 2009-09-15  
一个接口。两个实现类。2个实现类的名称一般是不一样的, 会生成2个ID不一样的bean,
按照id去用就行了, 如果是不同package中的名称一样的实现类,按照上面的方法去做就行了.
1 楼 userya 2009-09-15  
thinkinperson 写道
请问有这个需要吗?能在什么场景中用这个呢?annocation不好吗?
如果按你的设计。一个接口。两个实现类。你怎么能判断到底是使用了哪个实现类呢?

jdk1.4没有Annotation ,写Annotation有时候觉得多余,能不写就不写
一个接口2个实现类的情况你可以在service.xml 按照getBeanId方法的规则为这个bean取个ID配置,在MyXmlWebApplicationContext.java不会覆盖有这个Id的配置.

相关推荐

    Autofac的ServiceLocator模式应用,零配置

    总结来说,Autofac的ServiceLocator模式应用结合零配置,使得我们可以更轻松地管理和解耦应用程序中的组件。通过自动扫描、特性注解和模块化,我们可以减少大量手动配置,同时保持代码的清晰和可维护性。在`...

    ssh零配置_项目Demo

    标题中的“ssh零配置_项目Demo”指的是使用SSH(Spring、Struts、Hibernate)三大框架进行开发时的无配置或最少配置方式。SSH是Java Web开发中常用的三个开源框架,它们分别是Spring负责依赖注入和事务管理,Struts...

    spring+hibernate+maven零配置

    本文将深入探讨如何结合这三个工具进行“零配置”开发。 首先,让我们了解这三个组件的核心功能: 1. Spring:Spring是一个全面的Java应用框架,它提供了依赖注入(DI)和面向切面编程(AOP)等核心特性,用于简化...

    SSH框架集成注解零配置

    SSH框架集成注解零配置是现代Java Web开发中一种高效且流行的方式,SSH指的是Spring、Struts和Hibernate这三个开源框架的首字母缩写。Spring负责依赖注入和事务管理,Struts处理MVC模式中的控制器部分,而Hibernate...

    SSH零配置,完全注解方式工程

    这个"SSH零配置,完全注解方式工程"是一个示例项目,它展示了如何在不使用XML配置文件的情况下,通过Java注解来配置和使用SSH框架。 首先,Spring框架是应用上下文和依赖注入(DI)的核心。在传统配置中,我们会在...

    SSH官网最新包整合(全注解零配置)

    这个整合包被称为"SSH全注解零配置整合",意味着它利用了注解来减少XML配置文件的数量,使得项目设置更加简洁和高效。以下是这些技术及其集成的关键知识点: 1. **Struts2**: - **注解配置**:Struts2允许开发者...

    spring4+struts2.3.16.3+hibernate4.3.6零配置

    sshdemo这个压缩包中,很可能是包含了实现SSH零配置的示例代码,包括但不限于实体类、DAO接口及其实现、Service接口及其实现、Action类以及相关的Java配置类。开发者可以通过学习这些示例,快速理解如何在实际项目中...

    Struts+Spring+Hibernate注解零配置整合

    本项目"Struts+Spring+Hibernate注解零配置整合"的目标是展示如何通过注解方式实现这三大框架的无缝集成,从而减少XML配置文件的使用,提高开发效率和代码可读性。 在传统的Struts、Spring和Hibernate整合中,大量...

    零xml配置项目

    这意味着开发者将主要通过Java配置类、@Component注解、@Autowired自动装配、@Service、@Repository和@Controller等来构建和管理bean。 综上所述,这个项目是一个以Spring框架为基础,采用全注解配置的Web应用,它...

    SSH整合,纯注解,包含事务,零配置

    同时,项目还包含了事务管理,确保数据的一致性,实现了零配置,这意味着开发者几乎无需手动配置就能快速启动和运行应用。 1. Spring框架:Spring是Java领域的一个轻量级框架,核心特性是依赖注入(Dependency ...

    zk+hibernate+spring零配置

    标题中的"zk+hibernate+spring零配置"是一个集成开发环境的配置主题,涉及到三个重要的Java技术框架:ZooKeeper、Hibernate和Spring。这些框架在企业级应用开发中广泛使用,尤其是对于分布式系统和数据持久化处理。...

    spring无web.xml零配置

    在现代的Spring框架开发中,"spring无web.xml零配置"是一种常见的实践,它通过Java配置(javaconfig)替代了传统的XML配置方式。这种方式使得应用更加灵活,代码更易于理解和维护。下面我们将深入探讨这个主题。 ...

    Xfire配置Web Service+Spring+Hibernate详细流程

    本文将深入解析如何使用Xfire来配置并集成这三个核心技术,旨在提供一个从零开始的详细步骤指南。 #### 一、项目初始化 1. **创建WebService Project** - 在开发环境中(例如Eclipse或MyEclipse),选择新建项目...

    spring、spring mvc、hibernate 之零配置之路源代码

    这个"spring、spring mvc、hibernate 之零配置之路源代码"压缩包很可能是为了帮助开发者理解这三个框架如何协同工作,以及如何实现"零配置",即最小化XML配置,最大化依赖注入和自动化配置。 首先,Spring框架是...

    Spring3.1+Hibernate4.0+Struts2.3.1 零配置功能已实现

    在本项目中,"Spring3.1+Hibernate4.0+Struts2.3.1 零配置功能已实现"表示的是一个基于三大主流Java Web框架——Spring、Hibernate和Struts2的集成应用,且重点在于使用了注解(Annotation)进行零配置设置。...

    ssh框架源码 零配置 带注解

    在零配置的情况下,Spring使用@Component、@Service、@Repository和@Controller等注解来声明bean,通过@ComponentScan自动发现并注册这些bean。 Struts框架是SSH中的视图层组件,主要负责处理HTTP请求和响应。它...

    基于annotation s2sh实现零配置的CRM

    【基于Annotation的S2SH实现零配置CRM】 在IT行业中,CRM(Customer Relationship Management)系统是一种用于管理企业与客户之间关系的重要工具。S2SH,即Struts2、Spring和Hibernate的组合,是Java Web开发中常用...

    零配置spring 整合cxf、struts2

    然而,这里的“零配置”可能指的是通过注解驱动的方式,减少或消除XML配置文件,使得Spring、CXF和Struts2的集成更加简洁。 Spring与CXF的整合主要是为了创建和消费Web服务。CXF是一个开源的Web服务框架,它支持...

    spring3零配置注解实现Bean定义

    标题《spring3零配置注解实现Bean定义》中蕴含的知识点主要包括Spring框架中的Bean定义配置方法的演进,特别是从Spring 2.5到Spring 3版本的过渡过程中,对于注解方式实现Bean定义的支持如何被引入和优化。...

    spring+springmvc+jpa零配置注解开发

    在“spring+springmvc+jpa零配置注解开发”项目中,我们将深入探讨如何利用注解驱动的配置,避免XML配置,实现更简洁、高效的开发流程。 首先,让我们关注“零配置”这个概念。在传统的Spring应用中,开发者需要在...

Global site tag (gtag.js) - Google Analytics