`

关于ostocy-jshop2.0升级到注解版本的过程总结

阅读更多

 

首先我要感谢下【北京-痕迹】同学在这个过程中的帮助,让我能及时完成这部分工作。也让产品有了一个新的版本,新的编码体验。接下来就说下基本情况和过程吧!

 

本分分为如下几个部分:

A, 原始版本介绍

B, 注解版本介绍

C, 注解过程疑难问题总结

 

开源地址:http://code.google.com/p/ostocy-jshop/  完全开源

 

A, 原始版本是基于struts2+spring2.5+hibernate3+freemarker构件的。完全没有使用注解,所以在整个编码从daoaction的过程都需要在applicationContext.xml和多个struts.xml中配置(我为了区分业务,定义了多个struts2的配置文件)。

对于团队合作开发来说太多配置文件每次加入新方法都需要修改是很不好的,很容易造成svn的冲突。

        

 

B, 注解版本的构件也是基于原始版本的,但是使用了注解。具体使用了spring的注解给类进行依赖注入,用struts2的注解完成页面控制和拦截器设定。本来有想过想用spring mvc代替action层,但是这样会破坏了现有较为完好的逻辑和页面控制。所以放弃了。再者个人对spring mvc 不怎么熟悉。

 

这里来一个applicationContext.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"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation=" 
          http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
          http://www.springframework.org/schema/tx 
          http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
          http://www.springframework.org/schema/context 
          http://www.springframework.org/schema/context/spring-context-2.5.xsd 
          http://www.springframework.org/schema/aop 
          http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" default-autowire="byName">

	<aop:aspectj-autoproxy>
	
	</aop:aspectj-autoproxy>
	<context:component-scan base-package="com.jshop" />
	<context:annotation-config />
	<context:property-placeholder location="classpath*:*.properties" />

	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<property name="driverClass" value="${jdbc.driver}" />
		<property name="jdbcUrl" value="${jdbc.url}" />
		<property name="user" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="initialPoolSize" value="${pool.initialPoolSize}" />
		<property name="minPoolSize" value="${pool.minPoolSize}" />
		<property name="maxPoolSize" value="${pool.maxPoolSize}" />
		<property name="maxIdleTime" value="${pool.maxIdleTime}" />
		<property name="acquireIncrement" value="${pool.acquireIncrement}" />
		<property name="checkoutTimeout" value="${pool.checkoutTimeout}" />
		<property name="maxIdleTimeExcessConnections" value="${pool.maxIdleTimeExcessConnections}" />
	</bean>
	<!-- 邮箱服务器配置 -->
	<bean id="javamailsenderimpl" class="org.springframework.mail.javamail.JavaMailSenderImpl">
		<property name="host" value="${email.host}"></property>
		<property name="defaultEncoding" value="${email.defaultEncoding}"></property>
		<property name="port" value="${email.port}"></property>
		<property name="username" value="${email.username}"></property>
		<property name="password" value="${email.password}"></property>
		<property name="javaMailProperties">
			<props>
				<prop key="mail.smtp.auth">${email.auth}</prop>
				<prop key="mail.smtp.timeout">${email.timeout}</prop>
			</props>
		</property>

	</bean>
	
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
		destroy-method="close">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="mappingDirectoryLocations">
         <list>
            <value>classpath:com/jshop/entity</value>
         </list>
       </property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect 
                                        </prop>
				<prop key="hibernate.show_sql">true</prop>
			</props>
		</property>
	</bean>
	 <bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref local="sessionFactory" />
		</property>
	</bean>
	
	<aop:config>
		<aop:advisor pointcut="execution(* com.jshop.action.service.*Service.*(..))" advice-ref="txAdvice"/>
	</aop:config>

	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="get*" read-only="true"/>
			<tx:method name="query*" read-only="true"/>
			<tx:method name="find*" read-only="true"/>
			<tx:method name="load*" read-only="true"/>
			<tx:method name="*" rollback-for="Exception"/>
		</tx:attributes>
	</tx:advice>
	
	 <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory">
			<ref bean="sessionFactory" />
		</property>
	</bean> 

	<!-- 配置异步线程执行器 -->  <!-- 为异步线程执行器 进注入  -->
	<bean id="taskExecutor"
		class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
		<!-- 设置核心池子的大小 -->
		<property name="corePoolSize" value="10"></property>
		<!-- 设置最大池子的大小  --> 
		<property name="maxPoolSize" value="30"></property>
	</bean>


</beans>

 从上到下,依次的内容解释为

 

<!--[if !supportLists]-->1, <!--[endif]-->default-autowire="byName" 要求spring按照name来依赖注入而不是类型。

<!--[if !supportLists]-->2, <!--[endif]-->context:component-scan base-package="com.jshop" 要求spring去扫描com.jshop下得所有类去解释注解。

<!--[if !supportLists]-->3, <!--[endif]-->context:property-placeholder location="classpath*:*.properties" 要求spring检索web-info下得文件,这里主要是给下面的数据库和邮箱信息提供了properties形式的保存而已。

<!--[if !supportLists]-->4, <!--[endif]--><value>classpath:com/jshop/entity</value> 要求spring去搜索这个目录下得所有数据库映射文件,以前都是一个一个写的,现在让他自己搜索去,省事点。

<!--[if !supportLists]-->5, <!--[endif]-->com.jshop.action.service.*Service.*(..))" advice-ref="txAdvice"/>这个就是事务管理了,在service进行事务的回滚

<!--[if !supportLists]-->6, <!--[endif]--> <bean id="taskExecutor" 是邮件发送,是用的线程发送。

 

 

 接下来是摘录部分类的注解了

    Dao

 

 

@Repository("articleCategoryTDaoImpl")
public class ArticleCategoryTDaoImpl extends HibernateDaoSupport implements ArticleCategoryTDao {

 继承HibernateDaoSupport 就不用注入hibernateTemplate

 

     Service

 

@Service("articleCategoryTServiceImpl")
@Scope("prototype")
public class ArticleCategoryTServiceImpl implements ArticleCategoryTService {
	@Resource(name="articleCategoryTDaoImpl")
	private ArticleCategoryTDaoImpl articleCategoryTDaoImpl;

	
	public ArticleCategoryTDaoImpl getArticleCategoryTDaoImpl() {
		return articleCategoryTDaoImpl;
	}

 

 

 

Action@ParentPackage("jshop")

@Controller("articleCategoryTAction")
public class ArticleCategoryTAction extends ActionSupport {
	@Resource(name = "articleCategoryTServiceImpl")
	private ArticleCategoryTServiceImpl articleCategoryTServiceImpl;

 

 

 

接下来是struts.xml

 

<!--开发状态 -->  
    <constant name="struts.devMode" value="true" />
    <!-- 配置文件重新加载 -->  
    <constant name="struts.configuration.xml.reload" value="true" />
     <!-- convention类从新加载 -->  
    <constant name="struts.convention.classes.reload" value="true" />      
	<!-- 主题 -->  
    <constant name="struts.ui.theme" value="simple" />
	<constant name="struts.custom.i18n.resources" value="globalMessages" />
	
	<constant name="struts.i18n.encodeing" value="UTF-8" />
	
	<constant name="struts.convention.result.path" value="/" /> 

	<package name="jshop" extends="json-default" >
		<interceptors>
			<interceptor name="json" class="org.apache.struts2.json.JSONInterceptor" />
			<!-- 新增登录验证拦截器 -->
			<interceptor name="authoritylogin" class="com.jshop.action.interceptor.impl.AuthorityLogininterceptor"></interceptor>
			<!-- 定义全部变量拦截器!是否开启用户注册 -->
			<interceptor name="isusercanregister" class="com.jshop.action.interceptor.impl.MyIsusercanregisterInterceptor" />
			<!-- 定义全局变量拦截器 是否允许用户注册多个商城信息 -->
			<interceptor name="canuserregistermoreshopinfo"
				class="com.jshop.action.interceptor.impl.CanuserregistermoreshopinfoInterceptor"></interceptor>
			<!-- 定义全局变量拦截器是否允许发送激活邮件 -->
			<interceptor name="issendactivatemail" class="com.jshop.action.interceptor.impl.Issendactivatemail" />
			<interceptor-stack name="jshopdefaultStack">
				<!-- 将登录验证拦截器加入默认的拦截器栈中 -->
				<interceptor-ref name="authoritylogin">
					<param name="excludeMethods">adminlogin,uploadFiles,findAllCoupon,loginforAndroid,registerforAndroid</param>
				</interceptor-ref>
				<interceptor-ref name="defaultStack"></interceptor-ref>
				<interceptor-ref name="json"></interceptor-ref>
			</interceptor-stack>
			
		</interceptors>
		<default-interceptor-ref name="jshopdefaultStack" />

		<global-results>
			<result name="login" type="redirect">/jshop/admin/jump.jsp</result>
			<result name="isusercanregister">/usercenter/warning/warningmsg.jsp</result>
			<result name="canuserregistermoreshopinfo">/jshop/admin/error/adminerror.jsp
			</result>

		</global-results>
       
		<!-- 验证码 -->
		<action name="randomchecknum" class="com.jshop.tools.RandomCheckNumAction">
			<result type="stream">
				<param name="contentType">image/jpeg</param>
				<param name="inputName">inputStream</param>
			</result>
			<interceptor-ref name="defaultStack"></interceptor-ref>
		</action>
		
	</package>

 

 

解释如下

1<constant name="struts.convention.result.path" value="/" /> 这个很重要,告诉struts2我所有可以跳转的页面在项目根目录下。

2<package name="jshop" extends="json-default" >这个packageaction中的package要一致,因为这个影响到拦截器的作用域。

 

C,注解过程疑难问题总结

1, 注解默认的依赖注入对象是首字母小写的类名@Repository("articleCategoryTDaoImpl")对应的dao层的类就是ArticleCategoryTDaoImpl

2, Struts2配置文件中的拦截器作用域是和package有关的,所有action类都要统一packagestruts.xml一致。

3, Struts2的注解中有namespace注解,这个注解是会影响页面跳转的,应该是url了的显示问题,我这里没有用。需要在研究下。

4, Struts2我继承了json-default,所以绝大部分action层的struts2@Action没有显示的跳转页面,我都让前台的js做了页面控制。

 

0
1
分享到:
评论

相关推荐

    关于ostocy-jshop系统的商品体系结构说明文档

    《ostocy-jshop系统商品体系结构详解》 在IT行业中,构建一个高效、灵活的商品管理系统是电子商务平台的核心...同时,持续的系统优化和升级,使得ostocy-jshop系统在应对不断变化的电商环境时,保持了强大的竞争力。

    sdywcd-ostocy-jshop(在线商城程序)

    - "sdywcd-ostocy-jshop-a816fd9"可能代表项目的版本号或者Git提交ID,这通常用于版本控制和代码管理。 - 这个文件可能是源代码包,包含了项目的各个模块和资源文件,如XML布局文件、Java或Kotlin源码、图片、样式...

    jshoperv2:欧斯塔克在线商城系统

    ostocy-jshop的功能会陆续移植到jshoper3x中 欧斯塔克在线商城系统 基于java技术开发有如下特性: 1,使用spring + hibernate + struts2 + freemarker + jquery + css开发 2,在服务端有部分为android设备提供的...

    LTspice仿真:LDO电源电路学习与实践的利器

    内容概要:本文详细介绍了如何利用LTspice进行LDO(低压差线性稳压器)电源电路的仿真。首先讲解了如何导入LDO模型并配置仿真环境,接着深入探讨了瞬态分析、相位裕度、电源抑制比(PSRR)等关键仿真的具体步骤和注意事项。文中提供了多个实用的操作技巧,如通过调整补偿电容优化相位裕度,以及使用.step param命令批量测试不同参数的影响。此外,还分享了一些常见的仿真误区及其解决方法,帮助读者更好地理解和掌握LDO的设计与调试。 适合人群:电子工程专业学生、电源电路设计初学者、希望深入了解LDO特性的工程师。 使用场景及目标:适用于希望通过仿真工具提高LDO设计技能的人群。主要目标是掌握LDO的基本工作原理,学会使用LTspice进行各种类型的仿真分析,从而优化电路设计,确保系统的稳定性和性能。 其他说明:文章不仅提供详细的仿真步骤和技术细节,还附带了作者的实际经验和常见问题解决方案,使读者能够在实践中不断改进自己的设计思路。

    渝安集团员工职业发展通道设计方案.ppt

    渝安集团员工职业发展通道设计方案.ppt

    新能源电动汽车VCU与BMS的HIL硬件在环仿真技术及其模块化建模

    内容概要:本文详细介绍了新能源电动汽车中VCU(整车控制器)和BMS(电池管理系统)的HIL(硬件在环)仿真技术。首先阐述了整车建模的基础,包括电池、电机等关键部件的建模要点。接着分别解析了驾驶员模块、仪表模块、BCU整车控制器模块、MCU电机模块、TCU变速箱模块、BMS电池管理模块等多个子模块的功能和实现方式。最后强调了HIL仿真在电动汽车控制系统测试和优化中的重要性,特别是在降低成本和风险方面的作用。 适合人群:从事新能源汽车研发的技术人员,尤其是专注于VCU和BMS领域的工程师。 使用场景及目标:适用于需要深入了解电动汽车控制系统仿真技术的研发团队,在产品开发初期进行系统测试和优化,确保各子系统间的协同工作正常。 其他说明:文中提供了大量代码示例,帮助读者更好地理解和实践相关概念和技术细节。此外,还分享了一些实际项目中的经验和教训,如故障注入测试的具体应用场景等。

    如何应对一线人员春节后的离职潮.docx

    如何应对一线人员春节后的离职潮

    线性代数_GitHub_课件作业_教学辅助用途_1742837800.zip

    线性代数

    离职面谈表.xls

    离职面谈表.xls

    聚宽对接qmt大礼包,帮助你配置好交易实盘环境

    聚宽对接qmt大礼包,配备需要的全部软件:python3.9版本,qmt模拟安装包,pycharm安装包,talib包

    试用期转正表.xls

    试用期转正表.xls

    招聘数据分析.xls

    招聘数据分析.xls

    如何让新员工快速融入团队.docx

    如何让新员工快速融入团队

    电力电子仿真中并离网逆变器及无功补偿设备的控制策略与建模

    内容概要:本文详细介绍了并离网逆变器的两种主要控制策略——PQ控制和V/f控制,以及无功能量发生器(SVG)和有源电力滤波器(APF)的仿真模型。对于PQ控制,文章展示了如何将功率指令转化为电流指令,并强调了电网电压定向和限幅处理的重要性。V/f控制则用于离网模式,通过调节电压和频率来维持系统的稳定。SVG主要用于无功补偿,通过实时计算无功需求进行补偿。APF则专注于谐波检测和消除,利用自适应滤波器提高效率。此外,文中还提供了多个实用的小技巧,如仿真步长设置、模式切换时的前馈补偿等。 适合人群:从事电力电子仿真研究的技术人员,尤其是对逆变器控制策略感兴趣的工程师。 使用场景及目标:适用于需要深入理解和实现逆变器控制策略的研究项目,帮助工程师优化仿真模型,提升系统性能,确保仿真结果的准确性。 其他说明:文章不仅提供了详细的代码片段,还分享了许多实践经验,有助于读者避免常见错误,提高仿真成功率。

    Carsim与Simulink联合仿真中基于线性二自由度模型的卡尔曼滤波(KF)实现及优化

    内容概要:本文详细介绍了如何利用Carsim与Simulink进行联合仿真,通过线性二自由度模型和卡尔曼滤波(KF)来估计车辆的质心侧偏角和横摆角速度。首先搭建了联合仿真框架,Carsim提供车辆状态量,Simulink负责算法处理。文中展示了线性二自由度模型的状态方程及其参数设定,并深入探讨了KF的两种实现方式:S函数编程和Simulink内置模块。对于S函数实现,着重讲解了状态转移矩阵的动态更新以及噪声矩阵Q的调整策略,确保模型能够适应车速变化。而对于内置模块,则指出了其在灵活性方面的不足之处。此外,还讨论了联合仿真的配置要点,如数据接口同步、采样时间和信号处理等问题。 适合人群:从事车辆动力学研究、控制理论应用、自动化控制领域的工程师和技术人员。 使用场景及目标:适用于需要精确估计车辆质心侧偏角和横摆角速度的研究和开发项目,特别是在涉及ESP等主动安全系统的开发过程中。目标是提高估计精度,增强系统的鲁棒性和响应速度。 其他说明:文章提供了详细的代码片段和实践经验分享,帮助读者更好地理解和实施相关技术。建议在实际应用中根据具体需求选择合适的KF实现方式,并注意处理各种边界条件和异常情况。

    档案管理[03].pptx

    档案管理[03]

    风电与储能联合调频系统:基于Python的建模与优化

    内容概要:本文详细介绍了风电与储能联合调频系统的原理及其优化方法。首先解释了风电输出功率的波动性和对电网频率的影响,提出储能系统作为解决方案。文中展示了如何用Python生成风速数据并构建调频控制系统,重点讨论了PID控制器的设计以及SOC(荷电状态)管理策略。此外,还探讨了调频控制逻辑、硬件在环测试、风电功率预测模型(如LSTM)、调频效果验证方法及储能系统的物理限制等问题。最后强调了模型验证的重要性,提出了异常数据注入测试的方法。 适合人群:从事电力系统自动化、新能源发电及储能技术研发的专业人士,尤其是有一定编程基础的研究人员和技术工程师。 使用场景及目标:适用于需要理解和实施风电与储能联合调频项目的团队。主要目标是提高电网稳定性,减少风电波动带来的负面影响,同时延长储能系统的使用寿命。 其他说明:文中提供了大量实用的Python代码示例,涵盖了从数据生成到控制逻辑实现再到模型验证的全过程。对于希望深入理解风储调频系统的工作机制和技术挑战的人来说,是一份非常有价值的参考资料。

    HCIA-Storage V4.5 培训教材 合集

    HCIA-Storage V4.5 培训教材 合集

    基于S7-1200与博途V15的PLC小车自动往返控制系统设计与仿真

    内容概要:本文详细介绍了利用西门子S7-1200系列PLC和博途V15软件平台构建的小车自动往返控制系统。首先进行硬件组态,选择合适的CPU并配置输入输出点位,确保限位开关和急停按钮的有效接入。接着编写梯形图逻辑,实现小车在AB两点间的精确控制,采用定时器互锁机制避免电机损坏。然后设计触摸屏界面,通过WinCC创建动画效果展示小车运动状态,并设置按钮操作实现手动与自动模式切换。最后进行联合仿真实验,解决常见错误如变量地址配置不当等问题,确保系统稳定运行。 适合人群:工业自动化领域的工程师和技术人员,尤其是对PLC编程和HMI设计有一定基础的学习者。 使用场景及目标:适用于需要掌握PLC控制系统设计全流程的专业人士,帮助他们理解如何整合硬件组态、梯形图编程以及HMI开发,最终完成一个完整的自动化工程项目。 其他说明:文中提供了详细的调试经验和技巧,附带74分钟的操作录像资料,有助于读者更好地理解和实践相关知识点。

    公司员工关怀工作清单.xls

    公司员工关怀工作清单

Global site tag (gtag.js) - Google Analytics