spring打杂谈

来源:互联网 发布:java当时的下一天 编辑:程序博客网 时间:2024/04/28 20:23

Spring事务原理

2006年6月23日,15:35:00 | Dragonofson转到全文
统观spring事务,围绕着两个核心PlatformTransactionManager和TransactionStatus

spring提供了几个关于事务处理的类: 
TransactionDefinition //事务属性定义
TranscationStatus //代表了当前的事务,可以提交,回滚。
PlatformTransactionManager这个是spring提供的用于管理事务的基础接口,其下有一个实现的抽象类AbstractPlatformTransactionManager,我们使用的事务管理类例如DataSourceTransactionManager等都是这个类的子类。

一般事务定义步骤:
TransactionDefinition td = new TransactionDefinition();
TransactionStatus ts = transactionManager.getTransaction(td);
try
{ //do sth
  transactionManager.commit(ts);
}
catch(Exception e){transactionManager.rollback(ts);}
 

spring提供的事务管理可以分为两类:编程式的和声明式的。编程式的,比较灵活,但是代码量大,存在重复的代码比较多;声明式的比编程式的更灵活。

编程式主要使用transactionTemplate。省略了部分的提交,回滚,一系列的事务对象定义,需注入事务管理对象.
void add()
{
    transactionTemplate.execute( new TransactionCallback(){
        pulic Object doInTransaction(TransactionStatus ts)
       { //do sth}
    }
}

声明式:
使用TransactionProxyFactoryBean:
<bean id="userManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <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类似的操作。


Dragonofson 2006-06-23 15:35 发表评论
转到注释注释(0)

Spring视图解析器

2006年6月21日,11:10:00 | Dragonofson转到全文
1.InternalResourceViewResolver:适用于JSP来渲染视图,页面不使用国际化,不需要为不同得地区的用户显示不同的视图。
<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>
根据用户的地理位置渲染不同的视图。

Dragonofson 2006-06-21 11:10 发表评论
转到注释注释(0)

Spring MVC表单验证

2006年6月21日,9:39:00 | Dragonofson转到全文

采取的是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");
    }
   }
  }
 }
 



Dragonofson 2006-06-21 09:39 发表评论
转到注释注释(0)

关于Spring MVC构架

2006年6月20日,10:50:00 | Dragonofson转到全文

总体图表(参照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>



Dragonofson 2006-06-20 10:50 发表评论
转到注释注释(0)

Spring事务典型配置方法

2006年6月19日,15:31:00 | Dragonofson转到全文
类:
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不会去检查事务是否激活,也不会显示地启动或终止事务。也请注意,如果在声明的方法(事务属性中给出的)中抛出了未受查异常,则当前活动事务将回滚。



Dragonofson 2006-06-19 15:31 发表评论
转到注释注释(0)

Web中spring配置

2006年6月19日,14:44:00 | Dragonofson转到全文
1.web.xml

监听器
 <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);
    }
}
原创粉丝点击