本文介绍如何利用Eclipse插件Spring IDE在Eclipse中的使用。
Eclipse是目前非常流行的开发平台,开放扩展的架构让很多程序员找到了自己个性化的工作环境。
问题提出:
在采用Spring框架进行系统开发时,Bean的配置文件XML的书写、XML文件的内容校验及Bean之间的依赖关系查看等工作,如果能够采用合适的工具来完成,会成倍提高开发效率。
解决方法:
Spring IDE是Spring官方网站推荐的Eclipse插件,可提供在开发Spring时对Bean定义文件进行验证并以可视化的方式查看各个Bean之间的依赖关系等。
同时,建议结合Eclipse XMLBuddy插件进行XML文件编辑与校验,是个不错的选择。
安装说明
JDK:1.5.0 从http://java.sun.com上去下载安装
Eclipse:3.1.2 从http://www.eclipse.org 上去下载解压
Spring 1.2.8 从http://www.springframework.org 上去下载解压
Spring IDE 1.3.2 从http://springide.org 上去下载
XMLBuddy 2.0.72 从http://www.xmlbuddy.com/ 上去下载
Spring IDE 1.3.2 Update地址为:http://springide.org/updatesite/
管理技巧
Eclipse使用技巧之插件管理
提示:新下载的插件PlugIn一定不要都放在原始的Eclipse目录下去,一大堆,累死你:(
- 前提是你已经下载解压并设置好Eclipse工具,比如解压在E:/OpenSource/Eclipse/目录下,以下这个目录以%ECLIPSE_HOME%来进行表示;
- 此时默认的插件是在%ECLIPSE_HOME%/plugins目录中的;
- 在%ECLIPSE_HOME%下建立一个PlugInsNew的目录;
比如:E:/OpenSource/Eclipse/PlugInsNew
- 如果你下载了一个新的插件,比如叫做:XYZ
那么就在%ECLIPSE_HOME%/PlugInsNew/目录下建立XYZ目录,目录里面是eclipse目录,eclipse目录包含有features与plugins两个子目录;结构如下图所示:
- 把下载的新插件的文件放在以下相应目录中;
%ECLIPSE_HOME%/PlugInsNew/XYZ/eclipse/features
%ECLIPSE_HOME%/PlugInsNew/ XYZ/eclipse/plugins
- 建立相关的.link的文件;
然后在%ECLIPSE_HOME%/links目录里建立一个XYZ.link的文件
内容如是:
path=E:/OpenSource/Eclipse/PlugInsNew/XYZ
就一行这样的路径指示而已。
这样,如果你下载了多个插件就可以如法炮制建立多个Link文件,想加载哪个插件就把哪个插件的Link文件放到%ECLIPSE_HOME%/links的目录中即可,使用与管理都很方便,建议千万不要放在默认的安装目录中,这样对于升级Eclipse主程序也方便一些;当然如果你喜欢用Find and Install…进行安装的话也可以的;
如果上面你的%ECLIPSE_HOME%与此不同,请修改XYZ.link文件里的路径。
- 删除插件,先关闭Eclipse;
删除%ECLIPSE_HOME%/links/XYZ.link文件即可
删除%ECLIPSE_HOME%/PlugInsNew/XYZ整个目录及文件
- 重新启动Eclipse,这样就可以了。如果插件没有生效或者没有删除,请加上-clean进行启动Eclipse,即Eclipse.exe –clean
- 插件安装验证及记录详见:Eclipse的workspace下面的.metadata/.log文件,比如:%ECLIPSE_HOME%/workspace/.metadata/.log文件,有问题的话,打开这个文件看看并进行解决。
确认安装
此插件安装方法采用上一节的《Eclipse使用技巧之插件管理》
重新启动Eclipse后,在Help è About Eclipse SDK è Plug-in Details你可以看到由“Spring IDE Developer”提供的“Spring IDE”版本为“1.3.2”插件及相关的Graph、UI及UI Search插件,如下图所示:
相关要求
注意:为了让Spring IDE插件能够显示可视化的Bean结构图形及Bean之间的依赖关系,需要Eclipse GEF(Graphical Editing Framework)的支持,自己下载并解压安装,安装技巧同上《Eclipse使用技巧之插件管理》。
Spring 1.2系列当前最新的稳定版本为1.2.8,下载时可以选择包含Spring所依赖的一些开源包的文件spring-framework-1.2.8-with-dependencies.zip,如果你已经清楚并有了Spring所依赖的相关开源包,就单独下载spring-framework-1.2.8.zip即可。建议下载前者。
解压后目录结构及包的说明如下:
dist目录下是Spring的发布包,关于发布包下面会详细进行说明;
docs目录下是相关的文档,包括有Spring api的javadoc、reference参考指南、Spring的taglib标签使用文件及Spring MVC的MVC-step-by-step讲解与示例;
lib目录下是Spring所依赖的第三方开源包;
mock目录下是Spring辅助应用测试的Mock源程序;
samples目录下是Spring的示例源程序及简单的webapp示例框架的示例配置,值得好好学习的有jpetstore及petclinic,当然其它的countries、imagedb、tiles-example也可以好好参考一下;
src目录下是Spring的源程序;
test目录下Spring的单元测试源程序;
tiger目录下是Java 1.5 Tiger方面的相关及测试源程序。
Spring包结构说明
接下来详细说说dist目录下jar包的相关内容
spring.jar是包含有完整发布的单个jar包,spring.jar中除了spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下才会用到spring-mock.jar来进行辅助测试,正式应用系统中是用不得这些类的。
除了spring.jar文件,Spring还包括有其它13个独立的jar包,各自包含着对应的Spring组件,用户可以根据自己的需要来选择组合自己的jar包,而不必引入整个spring.jar的所有类文件。
spring-core.jar
这个jar文件包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工具类。
spring-beans.jar
这个jar文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。如果应用只需基本的IoC/DI支持,引入spring-core.jar及spring-beans.jar文件就可以了。
spring-aop.jar
这个jar文件包含在应用中使用Spring的AOP特性时所需的类。使用基于AOP的Spring特性,如声明型事务管理(Declarative Transaction Management),也要在应用里包含这个jar包。
spring-context.jar
这个jar文件为Spring核心提供了大量扩展。可以找到使用Spring ApplicationContext特性时所需的全部类,JDNI所需的全部类,UI方面的用来与模板(Templating)引擎如Velocity、FreeMarker、JasperReports集成的类,以及校验Validation方面的相关类。
spring-dao.jar
这个jar文件包含Spring DAO、Spring Transaction进行数据访问的所有类。为了使用声明型事务支持,还需在自己的应用里包含spring-aop.jar。
spring-hibernate.jar
这个jar文件包含Spring对Hibernate 2及Hibernate 3进行封装的所有类。
spring-jdbc.jar
这个jar文件包含对Spring对JDBC数据访问进行封装的所有类。
spring-orm.jar
这个jar文件包含Spring对DAO特性集进行了扩展,使其支持 iBATIS、JDO、OJB、TopLink,因为Hibernate已经独立成包了,现在不包含在这个包里了。这个jar文件里大部分的类都要依赖spring-dao.jar里的类,用这个包时你需要同时包含spring-dao.jar包。
spring-remoting.jar
这个jar文件包含支持EJB、JMS、远程调用Remoting(RMI、Hessian、Burlap、Http Invoker、JAX-RPC)方面的类。
spring-support.jar
这个jar文件包含支持缓存Cache(ehcache)、JCA、JMX、邮件服务(Java Mail、COS Mail)、任务计划Scheduling(Timer、Quartz)方面的类。
spring-web.jar
这个jar文件包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。
spring-webmvc.jar
这个jar文件包含Spring MVC框架相关的所有类。包含国际化、标签、Theme、视图展现的FreeMarker、JasperReports、Tiles、Velocity、XSLT相关类。当然,如果你的应用使用了独立的MVC框架,则无需这个JAR文件里的任何类。
spring-mock.jar
这个jar文件包含Spring一整套mock类来辅助应用的测试。Spring测试套件使用了其中大量mock类,这样测试就更加简单。模拟HttpServletRequest和HttpServletResponse类在Web应用单元测试是很方便的。
如何选择这些发布包,决定选用哪些发布包其实相当简单。如果你正在构建Web应用并将全程使用Spring,那么最好就使用单个全部的spring.jar文件;如果你的应用仅仅用到简单的Inversion of Control / Dependency Injection(IoC/DI)容器,那么只需spring-core.jar与spring-beans.jar即可;如果你对发布的大小要求很高,那么就得精挑细选了,只取包含自己所需特性的jar文件了。采用独立的发布包你可以避免包含自己的应用不需要的全部类。当然你可以采用其它的一些工具来设法令整个应用包变小,节省空间的重点在于准确地找出自己所需的Spring依赖类,然后合并所需的类与包就可以了。Eclispe有个插件叫ClassPath Helper可以帮你找找所依赖的类。
Spring包依赖说明
spring-core.jar需commons-collections.jar,spring-core.jar是以下其它各个的基本。 spring-beans.jar需spring-core.jar/cglib-nodep-2.1_3.jar spring-aop.jar需spring-core.jar/spring-beans.jar/cglib-nodep-2.1_3.jar/aopalliance.jar spring-context.jar需 spring-core.jar/spring-beans.jar/spring-aop.jar/commons-collections.jar/aopalliance.jar spring-dao.jar需spring-core.jar/spring-beans.jar/spring-aop.jar/spring-context.jar spring-jdbc.jar需spring-core.jar/spring-beans.jar/spring-dao.jar spring-web.jar需spring-core.jar/spring-beans.jar/spring-context.jar spring-webmvc.jar需spring-core.jar/spring-beans.jar/spring-context.jar/spring-web.jar spring-hibernate.jar需 spring-core.jar/spring-beans.jar/spring-aop.jar/spring-dao.jar/spring-jdbc.jar/spring-orm.jar/spring-web.jar/spring-webmvc.jar spring-orm.jar需 spring-core.jar/spring-beans.jar/spring-aop.jar/spring-dao.jar/spring-jdbc.jar/spring-web.jar/spring-webmvc.jar spring-remoting.jar需 spring-core.jar/spring-beans.jar/spring-aop.jar/spring-dao.jar/spring-context.jar/spring-web.jar/spring-webmvc.jar spring-support.jar需 spring-core.jar/spring-beans.jar/spring-aop.jar/spring-dao.jar/spring-context.jar/spring-jdbc.jar spring-mock.jar需spring-core.jar/spring-beans.jar/spring-dao.jar/spring-context.jar/spring-jdbc.jar
插件介绍
我们简单地创建一个示例工程,里面包含有一个接口类与两个实现该接口的实现类进行演示说明使用的方法。
需要引入spring.jar、commons-logging.jar、log4j.jar
单个引入需要引入spring-core.jar、spring-beans.jar、spring-context.jar
接口类:IHelloWorld.java
public interface IHelloWorld { String sayHelloWorld(); }
实现类一:HelloWorld1.java
public class HelloWorld1 implements IHelloWorld { public HelloWorld1() { super(); } public String sayHelloWorld() { return "Hello World HelloWorld1"; } }
实现类二:HelloWorld2.java
public class HelloWorld2 implements IHelloWorld { public HelloWorld2() { super(); } public String sayHelloWorld() { return "Hello World HelloWorld2"; } }
根据常用的三层与Spring的最佳实践,将配置文件分成了四个
beanRefFactory.xml负责总装,由SingletonBeanFactoryLocator来装入
通过ClassPathXmlApplicationContext来把其它三个模块的文件引入
beanRefDataAccess.xml负责DAO,与数据库相关的bean都定义在这里
beanRefService.xml负责Service层的bean定义
beanRefMVC.xml负责Spring MVC方面相关的bean定义等等
以下配置文件的bean定义为演示所用,各自的内容如下:
beanRefFactory.xml的内容如下:
<xml version="1.0" encoding="UTF-8"> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="beanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext"> <constructor-arg> <list> <value>beanRefDataAccess.xml</value> <value>beanRefService.xml</value> <value>beanRefMVC.xml</value> </list> </constructor-arg> </bean> </beans>
beanRefDataAccess.xml的内容如下:
<xml version="1.0" encoding="UTF-8"> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="helloWorldDAO1" class="HelloWorld1"/> <bean id="helloWorldDAO2" class="HelloWorld2"/> </beans>
beanRefService.xml的内容如下:
<xml version="1.0" encoding="UTF-8"> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="helloWorld1" class="HelloWorld1"/> <bean id="helloWorld2" class="HelloWorld2"/> <bean id="springDemoConstructor" class="SpringDemoConstructor"> <constructor-arg> <value>Spring IDE Constructor</value> </constructor-arg> <property name="helloWorld"> <ref bean="helloWorld1"></ref> </property> </bean> <bean id="springDemoSetter" class="SpringDemoSetter"> <property name="hello" value="Spring IDE Setter"/> <property name="helloWorld"> <ref bean="helloWorld2"></ref> </property> </bean> </beans>
beanRefMVC.xml的内容如下:
<xml version="1.0" encoding="UTF-8"> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="helloWorldMVC1" class="HelloWorld1"/> <bean id="helloWorldMVC2" class="HelloWorld2"/> </beans>
右键项目工程:可以看到“Add Spring Project Nature”菜单,单击它
细心的你一定可以看到项目工程SpringIDEDemo前面的图标变成了一个S的标志,而不是原来的J,当然项目里与Spring相关的文件都会在图标上显示一个S标志。J
右键弹出的菜单里就会有个“Remove Spring Project Nature”的菜单了。
你选择这个菜单进行移除后就不能进行以下的相关操作了。
Window è Show View è Other… è 可以看到Spring IDE,打开它,如下所示,所中它并确定。
可以看到如下的视图,右键工程的名称,在弹出的Properties菜单上点击它
弹出属性框,让我们来添加配置文件
确定后,可以看到刚才选择的四个配置文件已经在里面了,再次确定。
在Spring Beans视图里展开工程后,便可以看到增加进来的四个配置文件了。
也可以将配置文件放到配置集合里,如下所示:
这样确定以后,可以看到四个文件都属于Service的节点下面,如下所示。
再次确定后,在Spring Beans视图里看到Service节点,展开它,可以看到所有配置文件里的bean都在这里列出来了。
展开显示两个定义的bean结点,右键其中的一个结点,弹出四个菜点,最后一个就是上面的配置菜单,不再讲解了,我们选中“Open Config File”菜单
于是就会自动打开配置文件,并定位到bean的定义位置上面去了,如下所示,方便进行查看与改动。
在右键弹出的菜单点选中“Open Bean Class”,
就会自动定位到对应的类文件里去了,如下所示。
在右键弹出的菜单点选中“Show Graph”,
就会把当前这个bean以图形的方式显示出来,如下所示。
但是这个演示的文件仅是一个独立的bean,没有任何关联等,下面会演示关联等。
在Spring Beans视图里展开工程后,选中src/beanRefSerice.xml配置文件,在右键弹出的菜单点选中“Show Graph”
就会把当前整个配置文件的内容以bean图形的方式显示出来,如下所示。
以下演示bean的引用及构造注入与setter注入何关联等,更多的操作类似了。
定义一个接口类ISpringDemo.java,有两个方法
public interface ISpringDemo { IHelloWorld getHelloWorld(); String getHello(); }
实现类一SpringDemoConstructor.java,含有构造注入及setter注入
public class SpringDemoConstructor implements ISpringDemo { private String hello; private IHelloWorld helloWorld; public SpringDemoConstructor(String hello) { this.hello = hello; } public String getHello() { return hello; } public IHelloWorld getHelloWorld() { return helloWorld; } public void setHelloWorld(IHelloWorld helloWorld) { this.helloWorld = helloWorld; } }
实现类二SpringDemoSetter.java,都是setter注入
public class SpringDemoSetter implements ISpringDemo { private String hello; private IHelloWorld helloWorld; public String getHello() { return hello; } public void setHello(String hello) { this.hello = hello; } public IHelloWorld getHelloWorld() { return helloWorld; } public void setHelloWorld(IHelloWorld helloWorld) { this.helloWorld = helloWorld; } }
配置文件beanRefService.xml增加bean定义,成为如下,红字为新增的
<xml version="1.0" encoding="UTF-8"> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="helloWorld1" class="HelloWorld1"/> <bean id="helloWorld2" class="HelloWorld2"/> <bean id="springDemoConstructor" class="SpringDemoConstructor"> <constructor-arg> <value>Spring IDE Constructor</value> </constructor-arg> <property name="helloWorld"> <ref bean="helloWorld1"></ref> </property> </bean> <bean id="springDemoSetter" class="SpringDemoSetter"> <property name="hello" value="Spring IDE Setter"/> <property name="helloWorld"> <ref bean="helloWorld2"></ref> </property> </bean> </beans>
注意:
如果bean是定义在同一个文件里的可以用
<ref local="helloWorld2"></ref>
如果不是在同一个配置文件里的,要用
<ref bean="helloWorld2"></ref>
要不然会报到bean找不到!
这样配置完成后,我们切换到“Spring Beans”视图,在beanRefService.xml节点上右键打开“Show Graph”菜单,可以看到如下所示:
这时bean里面简单的引用关系就表现出来了。
在bean图上右键,会打开三个操作菜单:
Open Java Type即定位到bean的类文件上面;
Open Config File即定位到bean的xml配置文件上面;
Show In Beans View即定位到“Spring Beans”的视图里的具体某个节点上,如下所示。
此时我们可以在配置集合的Service节点上面右键,选择“Show Graph”
这样就会显示出所有的配置文件集合里的所有bean文件及其关联引用情况,如下图。
带圈的P图标表示是属性,即setter方法注入,带圈的C图标表示构造注入。箭头表示引用关系了。J
中间一排演示用的四个bean没有关联引入,就光杆司令地在那里排队了啦J
最下面的带圈的C后面又跟着一大排参数,表示集合类型的了。如list
Spring IDE提供错误检查功能,比如我在配置文件中输入一个不存在的类的名称,保存后,就会在边上出现红色提示,鼠标移上去就会出现提示信息,如下图所示。
当然也会有Problems视图里显示相应的错误信息,如下图:
XMLBuddy
由于打开XML文件时会根据XML文件里定义的DTD去网上查找相应的DTD文件,这样导至打开的时候会相当慢,特别是如果你的机器上不了外网的话,就更慢了。
解决的办法有两个:
一、在本机开启Web服务(如Tomcat等等),并设置端口为80,然后根据DTD 的目录结构建立相应的结构,并把DTD文件放进去。然后在hosts文件里把本机的地址映射到相应的DTD指定的网站去,如:
127.0.0.1// www.springframework.org
这样打开XML文件时就会在本机寻找DTD文件进行验证,速度就快很多了J
二、打开XMLBuddy插件的安装目录,并找到其中的cache目录,比如:%ECLIPSE_HOME%/PlugInsNew/xmlbuddy/eclipse/plugins/com.objfac.xmleditor_2.0.72/.cache
打开meta.xml文件,一看就知道怎么处理了吧,如法炮制,选把DTD文件拷贝到这个cache目录里,再增加内容到meta.xml里来,比如:
<file> <pub>-//SPRING//DTD BEAN//EN</pub> <abs>http://www.springframework.org/dtd/spring-beans.dtd</abs> <rel>spring-beans.dtd</rel> </file>
要增加其它的DTD文件方法类似,不断地增加说明与DTD文件即可。
于是在编辑XML文件时就会有相关的提示及错误提示信息,可以减少一些书写XML文件时发生的低级错误了。
测试与运行
先建立一个Log4J的配置文件log4j.properties,内容如下
# Set root logger level to ERROR and its only appender to R. log4j.rootLogger = INFO,R # R is set to be a DailyRollingFileAppender. log4j.appender.R = org.apache.log4j.DailyRollingFileAppender log4j.appender.R.File = Application.log log4j.appender.R.DatePattern = yyyy-MM-dd'.log' log4j.appender.R.layout = org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n
再创建一个ServiceFactory.java静态类,用来做单元测试方便一些
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.access.BeanFactoryLocator; import org.springframework.beans.factory.access.BeanFactoryReference; import org.springframework.beans.factory.access.SingletonBeanFactoryLocator; public final class ServiceFactory { private static BeanFactoryLocator bfLocator = null; private static BeanFactoryReference bfReference = null; private static BeanFactory factory = null; static { bfLocator = SingletonBeanFactoryLocator.getInstance(); bfReference = bfLocator.useBeanFactory("beanFactory"); factory = bfReference.getFactory(); } private ServiceFactory() { super(); } public static Object getBeanByName(final String beanName) { return factory.getBean(beanName); } }
做成静态的这样我们可以ServiceFactory .getBeanByName(“beanname”)就可以得到相应的bean了。
测试类SpringIDETest.java代码如下:
import junit.framework.TestCase; public class SpringIDETest extends TestCase { private IHelloWorld helloWorld = null; private ISpringDemo springDemo = null; private final static String hello1 = "Hello World HelloWorld1"; private final static String hello2 = "Hello World HelloWorld2"; private final static String helloset = "Spring IDE Setter"; private final static String hellocon = "Spring IDE Constructor"; public void testSpringBeans() { helloWorld = (IHelloWorld)ServiceFactory.getBeanByName("helloWorld1"); assertEquals(hello1,helloWorld.sayHelloWorld()); helloWorld = (IHelloWorld)ServiceFactory.getBeanByName("helloWorld2"); assertEquals(hello2,helloWorld.sayHelloWorld()); } public void testIoCConstructor() { //Constructor springDemo = (ISpringDemo)ServiceFactory.getBeanByName("springDemoConstructor"); assertEquals(hellocon,springDemo.getHello()); assertEquals(hello1,springDemo.getHelloWorld().sayHelloWorld()); } public void testIoCSetter() { //Setter springDemo = (ISpringDemo)ServiceFactory.getBeanByName("springDemoSetter"); assertEquals(helloset,springDemo.getHello()); assertEquals(hello2,springDemo.getHelloWorld().sayHelloWorld()); } }
Run As JUnit Test之,绿色打勾全部通过就收工走人了。。。J
当然也可以打开Application.log文件查看输出一些什么信息。
使用总结
此插件的功能不错:)对于Spring这样优雅的框架来说,再加上这个助手,真的是很美很美了,美美地喝上一杯咖啡吧。