最近配置了下spring+struts2+hibernate,spring+springmvc+hibernate,spring+springmvc+mybatis架构项目
最为先进的it中的一员 我们都知道现今的框架已从原来比较流行的spring+struts2+hibernate过渡到spring+springmvc+hibernate与spring+springmvc+mybatis
最近又爆出struts2相关漏洞的问题 除拉大公司有高级程序人员重新struts2架构 可以继续外,其他小型企业差不多都是spring+springmvc+hibernate与spring+springmvc+mybatis再加相关前端插件的架构啦
首先我们要知道
struts2是基于filter(过滤器)开发实现的;
spring是基于listener(监听器)开发实现的;
springmvc是基于servlet开发实现的;
那么他们的请求步骤及数值的传达方式就有一定的区别啦!可以自己下来查查!
在前端发送请求过来都是先经过listener到filter再到servlet访问流程的
而它们的周期:
Listener生命周期:一直从程序启动到程序停止运行。
ServletRequestListener:每次访问一个Request资源前,都会执行requestInitialized()方法,方法访问完毕,都会执行requestDestroyed()方法。
HttpSessionListener:每次调用request.getSession(),都会执行sessionCreated()方法,执行session.invalidate()方法,都会执行sessionDestroyed()方法。
ServletRequestAttributeListener:每次调用request.setAttribute()都会执行attributeAdded()方法,如果set的key在request里面存在,就会执行attributeReplacerd()方法,调用request.removeAttribute()方法,都会执行attributeRemoved()方法。
Filter生命周期:程序启动调用Filter的init()方法(永远只调用一次,具体看启动日志),程序停止调用Filter的destroy()方法(永远只调用一次,具体看关闭日志),doFilter()方法每次的访问请求如果符合拦截条件都会调用(程序第一次运行,会在servlet调用init()方法以后调用,不管第几次,都在调用doGet(),doPost()方法之前)。
Servlet生命周期:程序第一次访问,会调用servlet的init()方法初始化(只执行一次,具体看日志),每次程序执行都会根据请求调用doGet()或者doPost()方法,程序停止调用destory()方法(具体看结束日志)。
我们继续说他们的第一个配置web.xml 我想,不管你用什么架构模式,web.xml作为第一步配置是不变的,只是内容发生些改变而已
但是spring的配置是不变;
如果是spring+struts2+hibernate的web.xml配置:
就是多个struts2的(filter)配置
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>config</param-name>
<param-value>struts-default.xml,struts-plugin.xml,/struts.xml</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
如果是spring+springmvc+hibernate与spring+springmvc+mybatis的web.xml配置,就多个springmvc(servlet)的加载
<!-- 配置springMVC启动DispatcherServlete入口 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
可以比较下,就是标签名及部分内容变化了下 结构是没有变化的
接下来就是各自的struts2配置及springmvc相关的配置啦
这个区别就大啦 我就不细说啦,但我个人觉得springmvc更简单,方便,明了,实用点
其中controller代码的编写;struts2把controller普遍都是交给spring处理的,虽然struts2可以根据全类名自己处理;而springmvc是自己注解扫描的,然而springmvc说白啦就是spring的衍生架构!
现在我们说下spring+hibernate与spring+mybatis相关配置的区别 他们的配置都是写在一个配置文件里的;
然而他们的配置,说白啦,原理,结构,思想都一样,只是有些引用类,相关值发生啦变化而已:
我们先贴出spring+hibernate 的配置文件内容,你们自己比对下就清晰明了啦:
<?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:jaxws="http://cxf.apache.org/jaxws"
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-4.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<!-- 扫描有注解的文件 base-package 包路径 -->
<context:component-scan base-package="com"/>
<!-- 引入properties文件 -->
<context:property-placeholder location="classpath*:/appConfig.properties" />
<!-- 定义数据库连接池数据源bean destroy-method="close"的作用是当数据库连接不使用的时候,就把该连接重新放到数据池中,方便下次使用调用 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<!-- 设置JDBC驱动名称 -->
<property name="driverClass" value="${jdbc.Adriver}" />
<!-- 设置JDBC连接URL -->
<property name="jdbcUrl" value="${jdbc.Aurl}" />
<!-- 设置数据库用户名 -->
<property name="user" value="${jdbc.Ausername}" />
<!-- 设置数据库密码 -->
<property name="password" value="${jdbc.Apassword}" />
<property name="maxPoolSize" value="20"></property>
<!-- 设置数据库连接池的最小连接数 -->
<property name="minPoolSize" value="5"></property>
<!-- 设置数据库连接池的初始化连接数 -->
<property name="initialPoolSize" value="5"></property>
<!--最大空闲时间,300秒内未使用则连接被丢弃。若为0则永不丢弃。-->
<property name="maxIdleTime">
<value>300</value>
</property>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。-->
<property name="acquireIncrement">
<value>5</value>
</property>
</bean>
<!-- 配置sessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
<!-- hibernate的相关属性配置 -->
<property name="hibernateProperties">
<value>
<!-- 设置数据库方言 -->
hibernate.dialect=org.hibernate.dialect.MySQLDialect
<!-- 设置自动创建|更新|验证数据库表结构 -->
hibernate.hbm2ddl.auto=update
<!-- 是否在控制台显示sql -->
hibernate.show_sql=false
<!-- 是否格式化sql,优化显示 -->
hibernate.format_sql=true
<!-- 是否开启二级缓存 -->
hibernate.cache.use_second_level_cache=false
<!-- 是否开启查询缓存 -->
hibernate.cache.use_query_cache=false
<!-- 数据库批量查询最大数 -->
hibernate.jdbc.fetch_size=50
<!-- 数据库批量更新、添加、删除操作最大数 -->
hibernate.jdbc.batch_size=50
<!-- 是否自动提交事务 -->
hibernate.connection.autocommit=true
<!-- 指定hibernate在何时释放JDBC连接 -->
hibernate.connection.release_mode=auto
<!-- 创建session方式 hibernate4.x 的方式 -->
hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
<!-- javax.persistence.validation.mode默认情况下是auto的,就是说如果不设置的话它是会自动去你的classpath下面找一个bean-validation**包
所以把它设置为none即可 -->
javax.persistence.validation.mode=none
</value>
</property>
<!-- 自动扫描实体对象 com.azj.entity的包结构中存放实体类 -->
<!--sessionFactory 里的class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" -->
<!--<property name="packagesToScan" value="com.wzj.entity"/>满足注解实体类 -->
</bean>
<!-- 定义事务管理 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 事务执行方式
REQUIRED:指定当前方法必需在事务环境中运行,
如果当前有事务环境就加入当前正在执行的事务环境,
如果当前没有事务,就新建一个事务。
这是默认值。
-->
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="import*" propagation="REQUIRED" />
<!--
指定当前方法以非事务方式执行操作,如果当前存在事务,就把当前事务挂起,等我以非事务的状态运行完,再继续原来的事务。
查询定义即可
read-only="true" 表示只读
-->
<tx:method name="*" propagation="NOT_SUPPORTED" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 定义切面,在 com.azj.*.dao.*Dao.*(..)中执行有关的hibernate session的事务操作 -->
<aop:config>
<aop:pointcut id="serviceOperation" expression="execution(* com.azj.*.dao.*Dao.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />
</aop:config>
</beans>
我们在看下spring+mybatis的配置:
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 自动扫描注解包 -->
<context:component-scan base-package="com.azj.*">
<!-- //扫描时跳过 @Controller 注解的JAVA类(控制器) -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 引入配置文件 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:appConfig.properties" />
</bean>
<!-- 启动AOP支持 -->
<!-- <aop:aspectj-autoproxy/> -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<!-- 设置JDBC驱动名称 -->
<property name="driverClass" value="${jdbc.Adriver}" />
<!-- 设置JDBC连接URL -->
<property name="jdbcUrl" value="${jdbc.Aurl}" />
<!-- 设置数据库用户名 -->
<property name="user" value="${jdbc.Ausername}" />
<!-- 设置数据库密码 -->
<property name="password" value="${jdbc.Apassword}" />
<property name="maxPoolSize" value="20"></property>
<!-- 设置数据库连接池的最小连接数 -->
<property name="minPoolSize" value="5"></property>
<!-- 设置数据库连接池的初始化连接数 -->
<property name="initialPoolSize" value="5"></property>
<!--最大空闲时间,300秒内未使用则连接被丢弃。若为0则永不丢弃。-->
<property name="maxIdleTime">
<value>300</value>
</property>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。-->
<property name="acquireIncrement">
<value>5</value>
</property>
</bean>
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:com/azj/mapper/*.xml"></property>
<!--自动扫描实体类别名 -->
<property name="configLocation" value="classpath:mybatis.xml" />
</bean>
<!-- 自动扫描所有的Mapper接口与文件 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.azj.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
<!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
我们是不是可以看到他们都有扫描注解包,引用db.properties,引用c3p0数据源,建立SessionFactory的只是引用的class文件不一样而已,都有扫描注解实体类,都有事务管理
而spring-hibernate比spring-mybatis配置更加繁琐,hibernate本身就是重量级架构;但是他们的配置原理,结构都是差不多的;
以上便是spring+struts2+hibernate,spring+springmvc+hibernate,spring+springmvc+mybatis架构配置间的差异性啦