Spring的可扩展点做得比hibernate好多了,参考文档上就可以找到扩展spring配置文件的方法。利用在类路径的META-INF目录下加入spring.handlers和spring.schemas两个文件来作为扩展的入口。
我的思路是这样的,通过在一个spring总的配置文件中,比如applicationContext.xml中,加入一段我自定义的xml标签,在这个标签上定义我需要注册的spring的service bean在什么类路径下。然后spring在启动时,读取到该标签上定义的类路径,寻找该类路径下被我用annotation标注过的类,将该类注册到spring容器中。
第一步,定义标识service bean的annotation:
该annotation其实只需要一个属性,该service bean注册到spring中的id,所以我建立了如下的名字叫Bean的annotation类:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
//获取bean id
String id();
}
该annotation只能定义在类或者接口上,只有一个属性id,必填。用它标识后的service bean如下:
@Bean(id="sample.lesson.student")
public class StudentServiceBean implements IStudent {
第二步,扩展spring xml配置,定义service bean所在的目录:
前面已经说过,我们需要在applicationContext.xml这个总配置文件中定义service bean所在的目录。于是我在applicationContext.xml加入如下的tag:
<sa:annotation-autoload >
<sa:package>sample/service/lesson </sa:package>
<sa:package>sample/service/student</sa:package>
</sa:annotation-autoload>
加完后,eclipse的schemas校验功能已经告诉我们,出错误了。因为spring中并没有sa:annotation-autolaod和sa:package这样的标签,所以我们需要扩展spring校验用的schemas。扩展的方法就是在applicationContext文件中的beans根节点加入对schemas定义的代码:
<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"
xmlns:sa="http://leeon.iteye.com/context"
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.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://leeon.iteye.com/context http://leeon.iteye.com/context.xsd">
这段代码中,xmns:sa=http://leeon.iteye.com/context定义了xml tag的前缀是sa,而xsi:chemaLocation中定义的 http://leeon.iteye.com/context http://leeon.iteye.com/context.xsd指向了schemas xsd文件的位置。当然,不能让系统真的访问互联网去下载这个xsd了,可以通过在META-INF中创建的spring.handlers和spring.schemas文件类来定义schemas在本地类路径中的位置以及相关的handle这个schemas定义的xml tag的解析类,Spring加载时会通过这两个文件找到xsd和handler解析类的本地版本。
第三步,建立spring.handlers和spring.schemas以及相关的xsd和handler
于是在/META-INF中创建spring.schemas,内容如下:http\://leeon.iteye.com/context.xsd=leeon/extend/spring/context.xsd
这句话说明了真正校验我们自定义tag的xsd在leeon/extend/spring的类路径下
说明了位置后,我们就可以创建context.xsd,该xsd就是普通的校验xml用的xsd,不多做描述。可以参考以下代码:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://leeon.iteye.com/context" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://leeon.iteye.com/context" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
XML Schema for the Spring-Annotation module, it enables the use of annotations to configure your Spring-Framework application
]]>
</xsd:documentation>
</xsd:annotation>
<xsd:element name="annotation-autoload">
<xsd:annotation>
<xsd:documentation>
<![CDATA[Enables the scanning of anotated classes in the classpath, the scanDirs attribute tells to scan all open directories in the classpath, and the jarMarkerFile enables you to tell the scanner to loog for a file named different from to.properties in the jar files.]]>
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="package" type="xsd:string" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
<![CDATA[defines that the scanner will only include files that match with this.]]>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="pattern" type="xsd:string" default=".*\.class" use="optional" />
</xsd:complexType>
</xsd:element>
</xsd:schema>
接下来创建spring.handlers,内容如下:http\://leeon.iteye.com/context=leeon.extend.spring.EnableAnnotationHandler,这句话说明了Handler处理类所在的类路径,是真正处理我们在xml定义的tag的handler类。
创建时必须继承org.springframework.beans.factory.xml.NamespaceHandlerSupport类。该类是一个抽象类,必须实现的方式就是init,在这个方法中,告诉spring容器,处理哪些tag,需要哪些BeanDefinitionParser,代码如下:
public class EnableAnnotationHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("annotation-autoload",
new AnnotationAutoloadBeanDefinitionParser());
}
}
这里就是告诉spring容器,初始化处理annotation-autoload这个的xml element时,使用AnnotationAutoloadBeanDefinitionParser,该Parser是一个实现了BeanDefinitionParser接口的类。
第四步,实现自定义的BeanDefinitionParser
BeanDefinitionParser接口中,必须实现的方法是parse方法。顾名思义,我们要在这个方法中解析自定义的xml element,然后拿到在xml定义的service bean所在的类路径,再将该路径下被@Bean注册过的类,注册到spring的容器中。
public BeanDefinition parse(Element element, ParserContext parserContext) {
}
Parse的两个参数:
1. Element表示需要被我们解析的自定义的xml element对应的对象,这里对应的就是<sa:annotation-autoload>节点及其子节点。通过该对象我们可以获取我们配置的类路径,并搜索类路径,找到需要注册到spring容器中的类以及注册后的id。
2. ParserContext,BeanDefinitionParser的相关上下文环境,我们可以从这个参数中去到spring的类注册器,并进行spring bean的注册:
//从parserContext中获取bean注册器
BeanDefinitionRegistry bdr = parserContext.getRegistry();
//从创建一个spring bean的定义,并设定一下初始化值
//setBeanClass就是设定符合条件的service bean对应的class
final RootBeanDefinition rbd = new RootBeanDefinition();
rbd.setAbstract(false);
rbd.setBeanClass(c);
rbd.setSingleton(false);
rbd.setLazyInit(false);
//将spring bean的定义,通过id,注册到spring容器中
//这里的id就是从annotation中去到的service bean对应的spring bean id
bdr.registerBeanDefinition(id, rbd);
另外,该方法虽然需要返回值,但也是可以返回null的。定义好这个AnnotationAutoloadBeanDefinitionParser后,将spring bean注册的xml代码移植到annotation上就大功告成。当spring启动解析到<sa:annotation-autoload>标签时,就会将处理的过程交给AnnotationAutoloadBeanDefinitionParser,有Parser里的parse方法来解析到service bean所在路径,搜索,获取id和class,最后加载完成。
分享到:
相关推荐
ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ...
rapidsh-SSH经典整合框架-包括权限管理-文件上传下载-用户管理-分页-lookup
自己手动搭建的一个ssh框架,对于初学者有很好的帮助!数据库oracle,c3p0连接池……
java SSH框架--学生学籍管理系统
这是一个spring-boot整合ssm和ssh框架所需要的pom依赖文件
ssh框架-后台管理模板 包含mysql基础数据库
ssh框架配置文件的实例,教会大家使用ssh框架的xml配置
使用myeclipse8.5与mysql搭建的SSH框架,并含有登陆实例,自己创建users数据库表,直接就可以跑起来
SSH框架及配置文件
ssh配置文件ssh配置文件ssh配置文件ssh配置文件
│ 北京动力节点SSH前言-016-Log4j-日志输出控制文件的作用.mp4 │ 北京动力节点SSH前言-017-Log4j-日志的用途及Log4j.mp4 │ 北京动力节点SSH前言-018-Log4j-日志基础.mp4 │ 北京动力节点SSH前言-019-Log4j-Log4j...
数据库使用的是MySql 5.7,已导出为sql文件(blog.sql) 包括后台管理和前端展示两部分构成: * 后台使用Easyui进行开发的界面 * 前台使用Bootstrap开发的界面 前台和后台交互全部通过ajax传输json来进行数据...
这是我第一次用Spring+Struts2+Hibernate框架写的项目,数据库使用的是mysql,应该比较适合初学者
ssh框架事务管理applicationContext.xml配置文件
idea配置ssh框架
ssh框架简单示例,使用ssh框架实现简单的注册登录,适合初学习ssh框架的人来参考练习!
SSH三大框架集成或单独配置相关配置文件详解,超全!
提供一套SSH框架实现的办公自动化系统、供学习参考。
最基础的SSH框架应用,最基础的ssh框架使用案例
在JavaEE企业级开发中,以SSH2框架为核心的应用非常广,本文由大象根据项目实践经验,通过一个实例,详细的为大家讲解如何实现全注解式的开发。