spring打杂谈
来源:互联网 发布:java当时的下一天 编辑:程序博客网 时间:2024/04/28 20:23
Spring事务原理
spring提供了几个关于事务处理的类:
TransactionDefinition //事务属性定义
TranscationStatus //代表了当前的事务,可以提交,回滚。
PlatformTransactionManager这个是spring提供的用于管理事务的基础接口,其下有一个实现的抽象类AbstractPlatformTransactionManager,我们使用的事务管理类例如DataSourceTransactionManager等都是这个类的子类。
一般事务定义步骤:
spring提供的事务管理可以分为两类:编程式的和声明式的。编程式的,比较灵活,但是代码量大,存在重复的代码比较多;声明式的比编程式的更灵活。
编程式主要使用transactionTemplate。省略了部分的提交,回滚,一系列的事务对象定义,需注入事务管理对象.
声明式:
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="target"><ref local="userManagerTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
围绕Poxy的动态代理 能够自动的提交和回滚事务
org.springframework.transaction.interceptor.TransactionProxyFactoryBean
- PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
- PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
- PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
- PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
- PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
- PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
Spring视图解析器
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix"><value>/WEB-INF/JSP/</value></property>
<property name="suffix"><value>.jsp</value></property>
<property name="viewClass"><value>org.springframework.web.servlet.view.JstView</value></property>
//页面使用JSTL
</bean>
2.BeanNameViewResolver,XmlFileViewResover使用定制视图(PDF,Excel,图片)
BeanNameViewResolver(返回的是bean)
<bean id="beanNameViewResolver" class="org.spring.framework.web.servlet.view.BeanNameViewResovler">
<bean id="courseList" class="com.CourseList">//courseList we是 new ModelAndView("courseList","courses",courses);
<bean id="beanNameViewResolver" class="org.spring.framework.web.servlet.view.XmlFileViewResover">
<property name="location>
<value>/WEB-INF/traning-views.xml</value>
</property>
</bean>
3.<bean id="bundleViewResolver" class="org.springframework.web.servlet.view.ResourceViewResolver">
<property name="basename">
<value>view</value>
</property>
</bean>
根据用户的地理位置渲染不同的视图。
Spring MVC表单验证
采取的是spring action 中的例子
验证一个Student对象
1.implements Validator接口(org.springframework.validation.Validator)
public class StudentValidator implements Validator
{
public boolean supports(Class clazz)//必须实现的方法
{return clazz.equals(Student.class) ;
}
public void validate(Object command,Errors errors)
{
Student student =(Student)command;
// ValidationUtils.rejectIfEmpty (Errors errors, String field, String errorCode, String defaultMessage)
ValidationUtils.rejectIfEmpty(errors,"login","required.login","login is required");
ValidationUtils.rejectIfEmpty(errors,"password","required.password","Password is required");
ValidationUtils.rejectIfEmpty(errors,"firstName","required.firstName","firstNameis required");
ValidationUtils.rejectIfEmpty(errors,"lastName","required.lastName","lastNameis required");
ValidationUtils.rejectIfEmpty(errors,"city","required.login","cityis required");
validateEmail(student .email,errors);
validatePhone(student .phone,errors);
}
private static final String PHONE_REGXP="/(//({0,1}(//d{3})))/"
private void validatePhone(String phone, Errors erros)
{
ValidationUtils.rejectIfEmpty(errors,"phone","required.phone","phoneis required");
Perl5Util per5Util=new Perl5Util();
if(!per5Util.math(PHONE_REGXP,phone))
{
errors.reject("invalid.phone","Phone number is invalid");
}
}
private static final String Email_REGXP="/(//({0,1}(//d{3})))/"
private void validateEmail(String phone, Errors erros)
{
ValidationUtils.rejectIfEmpty(errors,"phone","required.phone","phoneis required");
Perl5Util per5Util=new Perl5Util();
if(!per5Util.math(Email_REGXP,email))
{
errors.reject("invalid.phone","Phone number is invalid");
}
}
}
2.配置bean
<bean id="methodNameResolver"
class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
<property name="paramName"><value>method</value>
</property>
<property name="defaultMethodName"><value>view</value>
</property>
</bean>
<property name="validator"><bean class="com.StudentValidator "/>
</property>
<property name="defaultMethodName"><value>view</value>
</property>
<bean name="/jsp/test.do" class="org.nightwalker.spaces.web.controller.TestController">
<property name="methodNameResolver">
<ref local="methodNameResolver"/>
</property>
</bean>
查看源代码:
MultiActionController类:
protected void bind(ServletRequest request, Object command) throws Exception {
logger.debug("Binding request parameters onto MultiActionController command");
ServletRequestDataBinder binder = createBinder(request, command);
binder.bind(request);
if (this.validators != null) {
for (int i = 0; i < this.validators.length; i++) {
//首先调用supports
if (this.validators[i].supports(command.getClass())) {
ValidationUtils.invokeValidator(this.validators[i], command, binder.getErrors());
}
}
}
binder.closeNoCatch();
}
类ValidationUtils:
public static void invokeValidator(Validator validator, Object obj, Errors errors) {
if (validator != null) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking validator [" + validator + "]");
}
if (obj != null && !validator.supports(obj.getClass())) {
throw new IllegalArgumentException("Validator " + validator.getClass() +
" does not support " + obj.getClass());
}
validator.validate(obj, errors);
if (logger.isDebugEnabled()) {
if (errors.hasErrors()) {
logger.debug("Validator found " + errors.getErrorCount() + " errors");
}
else {
logger.debug("Validator found no errors");
}
}
}
}
关于Spring MVC构架
总体图表(参照stucts)
DispatcherServlet=ActionServlet
HandlerMapping=Struts-config.xml
Controller=Action
ModelAndView=mapping.findforward(string) 中的string;
ViewResolver=mapping.findforward(string) 中string的解释器
特别注意:
1.在web.xml里面配置好
<servlet>
<servlet-name>springapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
不需要配置context-param
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springapp-servlet.xml</param-value>
</context-param>
DispatcherServlet 能够自动的到WEB-INF下面查找与他同名的后面接-servlet,.xml的配置文件。
(springapp-servlet.xml)
注意:DispatcherServlet 处理的跳转必须要在工程名下面。例如:工程名为:SpringMvc.则Http://localhost:8080/SpringMvc/test.htm可以跳转。
Http://localhost:8080/test.htm 不能跳转
详细说明MultiActionController的配置吧:
首先在bean.xml里面:
<bean id="methodNameResolver"
class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
<property name="paramName"><value>method</value> //相当于DispatchAction的method后面接需要触发的方法
</property>
//另一个触发方法的配置
//当提交coureList.htm时候触发coursesUnsorted方法,当提交coursesSort.htm时候触发coursesSortByDate方法
<property name="mapping">
<props>
<prop key="/coureList.htm">coursesUnsorted</prop>
<prop key="/coursesSort.htm">coursesSortByDate</prop>
</props>
</property>
</bean>
//默认方式页面跳转到Controller
<bean name="/jsp/test.do" class="org.nightwalker.spaces.web.controller.TestController">
<property name="methodNameResolver">
<ref local="methodNameResolver"/>
</property>
</bean>
//SimpleUrlHandlerMapping页面跳转到Controller
<bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHand">
<property name="mapping">
<props>
<prop key="/listCourses.htm">listCourseController</prop>
<prop key="/register.htm">registerController</prop>
<props>
</props>
</property>
</bean>
配置呢就这么简单。methodNameResolver指定了调用MultiActionController中方法的方式,例如,如果在你的MultiActionController中有如下方法:
public ModelAndView insertAccount(HttpServletRequest request,HttpServletResponse,Account account)
{
}
那么要调用这个方法,你的JSP页面的请求URL就应该这样写:
<form action="test.do?method=insertAccount">
</form>
至于绑定什么command和JSP是没有关系的。你在MultiActionController中的方法签名第三个参数是什么对象,Spring就会把request中参数的值绑定到方法签名的第三个对象中。
例子我倒是没有,最直接的办法就是去看一下MultiActionController的源代码,非常简单拉,一看就明白了。
protectedfinal ModelAndView invokeNamedMethod(String methodName, HttpServletRequest request, HttpServletResponse response)throwsException
{
// If last parameter isn't of HttpSession type, it's a command.
// 在这里,Spring会判断你的请求方法里面第三个参数的类型。如果第三个参数类型不是HttpSession,就认为是要绑定的command。
if(method.getParameterTypes().length >= 3 &&
!method.getParameterTypes()[method.getParameterTypes().length - 1].equals(HttpSession.class))
{
// 根据类型利用反射产生Command对象
Object command = newCommandObject(method.getParameterTypes()[method.getParameterTypes().length - 1]);
params.add(command);
// 绑定command对象
bind(request, command);
}
// 最后通过反射去调用你的方法,也就是说,在执行你的方法时,command已
// 经帮你绑定好拉,你直接用就可以了。
return(ModelAndView) method.invoke(this.delegate, params.toArray(newObject[params.size()]));
}
使用模板视图
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix"><value>/jsp</value></property>//前缀
<property name="suffix"><value>.jsp</value></property>//后缀
</bean>
Spring事务典型配置方法
public interface CustomerDAO {
public void createCustomer(Customer customer);
}
public class HibernateCustomerDAO implements CustomerDAO {
private HibernateTemplate hibernateTemplate = null;
public void setSessionFactory(SessionFactory sessionFactory) {
this.hibernateTemplate = new HibernateTemplate(sessionFactory, false);
}
public void createCustomer(Customer customer) {
this.hibernateTemplate.save(customer);
}
}
配置文件:
<bean id="customerDAOTarget" class="test.usecase.HibernateCustomerDAO">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>
<bean id="customerDAO" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="target"><ref bean="customerDAOTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="create*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
上述Spring配置片断定义了业务对象HibernateCustomerDAO,它包裹了Hibernate SessionFactory。注意,默认时,Spring中定义的JavaBean都是单例的,HibernateCustomerDAO也不例外。这意味:多个线程可能同时执行createCustomer()方法。
其次,配置了Hibernate事务管理器,它包裹了同一Hibernate SessionFactory实例。在事务管理器每次执行时,它都会完成如下几件事情。其一,检查Hibernate Session是否绑定到当前线程。如果已绑定,则直接使用它。如果还未绑定,事务管理器将告知Hibernate SessionFactory创建新的Session,然后将创建的Session绑定到当前线程。其二,如果当前没有处于活动的事务,则事务管理器将启动新的事务,并将Session包裹进来。否则,直接参与到活动事务中。
整个过程是通过使用Spring提供的TransactionProxyFactoryBean实现的。当然,这是一种以声明方式实现的事务管理过程。 TransactionProxyFactoryBean能够为业务对象创建代理对象,从而通过事务管理器管理事务。当每次通过代理对象调用createCustomer()方法时,事务管理器将根据事务属性管理事务。当前,Spring除了提供HibernateTransactionManager事务管理器外,还为JDBC数据源、JDO、TopLink提供了相应的事务管理器。
再来看看业务对象吧!当调用createCustomer()方法时,HibernateTemplate将查找绑定到当前线程的Hibernate Session。由于上述配置文件片断传入到HibernateTemplate构建器的第二个参数为false,因此如果没有绑定Hibernate Session,则将抛出未受查异常。这对于那些未正确配置事务管理功能的场和特别有用(注意,事务管理器很重要)。一旦事务管理配置好后,Hibernate Session将绑定到当前线程,从而启动事务。请注意,HibernateTemplate不会去检查事务是否激活,也不会显示地启动或终止事务。也请注意,如果在声明的方法(事务属性中给出的)中抛出了未受查异常,则当前活动事务将回滚。
Web中spring配置
监听器
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
在servlet上下文配置spring的配置文件
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/config/hibernate/applicationContext-hibernate.xml
/WEB-INF/config/spring/applicationContext-spring.xml
<!--/WEB-INF/config/spring/acegi-security-common.xml-->
</param-value>
</context-param>
2.得到Spring Bean
public class test extends action
{
private static ApplicationContext ctx = null;
public Object getBean(String name)
if(ctx == null)
{
ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servlet.getServletContext());
}
return ctx.getBean(name);
}
}
- spring打杂谈
- Spring杂谈
- Spring 杂谈
- Spring 杂谈
- spring 杂谈1
- Spring security深入杂谈
- Spring事务杂谈
- Spring security深入杂谈
- Spring security深入杂谈
- 编程杂谈-----spring
- Spring MVC 杂谈
- spring 事务杂谈
- 杂谈: 关于打赏的功能
- Spring AOP 实现机制杂谈
- spring boot 打jar包
- Java杂谈(十)--Spring
- JSF,Hibernate,Spring的整合与杂谈
- 杂谈
- 使用反射机制将一个类实例的值赋给DataTable某一行
- XML文件DTD路径解析问题(in Eclipse)
- 第三届“敏捷中国”技术大会将在北京丽亭华苑酒店召开
- MPlayer 在FS2410上的移植过程
- 自顶向下学搜索引擎——北大天网搜索引擎TSE分析及完全注释[4]小结
- spring打杂谈
- 大学毕业后再看会后悔一辈子
- 全文检索lucene学习笔记(三)
- 二叉树
- VisualFC 0.80.0601 Released!
- 大风今日开博
- 让我们泪流满面的电影经典台词
- 在VC++下对文件属性的获取与更改
- 如何从一个non-UCM vob中恢复用rmelem误删除的元素?