??xml version="1.0" encoding="utf-8" standalone="yes"?>99精品久久只有精品,国产精品热视频,www.久久久http://www.aygfsteel.com/mikechen/category/50934.html?sh)子商务技术架?/description>zh-cnWed, 04 Jul 2012 00:46:15 GMTWed, 04 Jul 2012 00:46:15 GMT60框架-quartzhttp://www.aygfsteel.com/mikechen/archive/2012/07/03/382090.html陈睿陈睿Tue, 03 Jul 2012 06:42:00 GMThttp://www.aygfsteel.com/mikechen/archive/2012/07/03/382090.htmlhttp://www.aygfsteel.com/mikechen/comments/382090.htmlhttp://www.aygfsteel.com/mikechen/archive/2012/07/03/382090.html#Feedback0http://www.aygfsteel.com/mikechen/comments/commentRss/382090.htmlhttp://www.aygfsteel.com/mikechen/services/trackbacks/382090.html一Qquartz?/strong>
       OpenSymphony 的Quartz提供了一个比较完的d调度解决Ҏ(gu)?/span>
       Quartz 是个开源的作业调度框架Q定时调度器Qؓ(f)?Java 应用E序中进行作业调度提供了单却强大的机制?/div>
       Quartz中有两个基本概念Q作业和触发器。作业是能够调度的可执行dQ触发器提供了对作业的调?br />
二:(x)quartz spring配置详解
  •  Z么不适用java.util.Timerl合java.util.TimerTask 
        1.主要的原因,适用不方便,特别是制定具体的q月日时分的旉Q而quartz使用cMlinux上的cron配置Q很方便的配|每隔时间执行触发?br />
        2.其次性能的原因,使用jdk自带的Timer不具备多U程Q而quartz采用U程池,性能上比timer高出很多?br />

  •    详解quartz在spring里面的配|?/strong>
    在spring里主要分ZU用方式:(x)W一U,也是目前使用最多的方式Qspring提供的MethodInvokingJobDetailFactoryBean代理c,通过雷利cȝ接调用Q务类的某个函敎ͼW二U?E序里实现quartz接口Qquartz通过该接口进行调度?br />
      主要讲解通过spring提供的代理类MethodInvokingJobDetailFactoryBean

        1.业务逻辑c?业务逻辑是独立的Q本w就与quartz解耦的Qƈ没有深入q去Q这对业务来讲是很好的一个方式?br />
                        public class  TestJobTask{
     

      /**
       *业务逻辑处理
       
*/
        public void   service(){
            /**业务逻辑*/
                ..
        }

}
       
    2.增加一个线E池
    <!-- U程执行器配|,用于d注册 -->
<bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
 <property name="corePoolSize" value="10" />
 <property name="maxPoolSize" value="100" />
 <property name="queueCapacity" value="500" />
</bean>

  3.定义业务逻辑c?br />
    <!-- 业务对象 -->
<bean id="testJobTask" class="com.mike.scheduling.TestJobTask" />


    4.增加quartz调用业务逻辑

    <!-- 调度业务 -->
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
 <property name="targetObject" ref="testJobTask" />
 <property name="targetMethod" value="service" />
</bean>

    5.增加调用的触发器Q触发的旉Q有两种方式Q?br />
     W一U触发时_(d)采用cMlinux的cronQ配|时间的表示发出丰富  
  <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
 <property name="jobDetail" ref="jobDetail" />
 <property name="cronExpression" value="10 0/1 * * * ?" />
</bean>
  Cron表达?#8220;10 */1 * * * ?”意ؓ(f)Q从10U开始,?分钟执行一?/span> 
  
    W二U,采用比较话的方式Q申明gq时间和间隔旉
  <bean id="taskTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
 <property name="jobDetail" ref="jobDetail" />
 <property name="startDelay" value="10000" />
 <property name="repeatInterval" value="60000" />
</bean>
  延迟10U启动,然后每隔1分钟执行一?/span> 

    6.开始调?br />
      <!-- 讄调度 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
 <property name="triggers">
  <list>
   <ref bean="cronTrigger" />
  </list>
 </property>
 <property name="taskExecutor" ref="executor" />
</bean>

   7.l束Q启动容器即可,已经spring和quartzl合完毕?/strong>

    Cron常用的表辑ּ
    "0 0 12 * * ?" 每天中午12点触?/span>
"0 15 10 ? * *" 每天上午10:15触发
"0 15 10 * * ?" 每天上午10:15触发
"0 15 10 * * ? *" 每天上午10:15触发
"0 15 10 * * ? 2005" 2005q的每天上午10:15触发
"0 * 14 * * ?" 在每天下?点到下午2:59期间的每1分钟触发
"0 0/5 14 * * ?" 在每天下?点到下午2:55期间的每5分钟触发
"0 0/5 14,18 * * ?" 在每天下?点到2:55期间和下?点到6:55期间的每5分钟触发
"0 0-5 14 * * ?" 在每天下?点到下午2:05期间的每1分钟触发
"0 10,44 14 ? 3 WED" 每年三月的星期三的下?:10?:44触发
"0 15 10 ? * MON-FRI" 周一臛_五的上午10:15触发
"0 15 10 15 * ?" 每月15日上?0:15触发
"0 15 10 L * ?" 每月最后一日的上午10:15触发
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 
"0 15 10 ? * 6L 2002-2005" 2002q至2005q的每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6#3" 每月的第三个星期五上?0:15触发

三:(x)quartz原理

    Ҏ(gu)上面spring的配|,我们比较清楚quartz的内部情况,下面我们主要详解配置涉及(qing)到的每个?/strong>
    1.我们先从最后一个步骤看PSchedulerFactoryBean Qscheduler的工厂实玎ͼ里面可以生出对应的多个jobDetail和triggerQ每个jobDetail对应trigger代表一个Q?br />         Quartz的SchedulerFactory是标准的工厂c,不太适合在Spring环境下用。此外,Z保证Scheduler能够感知 Spring容器的生命周期,完成自动启动和关闭的操作Q必让Scheduler和Spring容器的生命周期相兌。以便在Spring容器启动后, Scheduler自动开始工作,而在Spring容器关闭前,自动关闭Scheduler。ؓ(f)此,Spring提供 SchedulerFactoryBeanQ这个FactoryBean大致拥有以下的功能:(x) 
     1)以更具Bean风格的方式ؓ(f)Scheduler提供配置信息Q?nbsp;
     2)让Scheduler和Spring容器的生命周期徏立关联,相生相息Q?nbsp;
     3)通过属性配|部分或全部代替Quartz自n的配|文件?nbsp;
  2.jobDetail,表示一个可执行的业务调?br />  
  3.trigger:调度的时间计划,什么时候,每隔多少旉可执行等旉计划

  4.ThreadPoolTaskExecutorQ线E池Q用来ƈ行执行每个对应的jobQ提高效率,q也是上面提C推荐使用jdk自ntimer的一个很重要的原?/span>


陈睿 2012-07-03 14:42 发表评论
]]>框架-springhttp://www.aygfsteel.com/mikechen/archive/2012/02/29/370992.html陈睿陈睿Wed, 29 Feb 2012 06:45:00 GMThttp://www.aygfsteel.com/mikechen/archive/2012/02/29/370992.htmlhttp://www.aygfsteel.com/mikechen/comments/370992.htmlhttp://www.aygfsteel.com/mikechen/archive/2012/02/29/370992.html#Feedback0http://www.aygfsteel.com/mikechen/comments/commentRss/370992.htmlhttp://www.aygfsteel.com/mikechen/services/trackbacks/370992.html一Qspring概要

    单来_(d)Spring是一个轻量的控制反转(IoCQ和面向切面Q?a target="_blank" style="text-decoration: underline; color: #136ec2; ">AOPQ的容器框架?br />    控制反{——Spring通过一U称作控制反转(IoCQ的技术促q了松耦合。当应用了IoCQ一个对象依赖的其它对象?x)通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认ؓ(f)IoC与JNDI相反——不是对象从容器中查找依赖Q而是容器在对象初始化时不{对象请求就d依赖传递给它?div>
  ◆面向切面——Spring提供?a target="_blank" style="text-decoration: underline; color: #136ec2; ">面向切面~程的丰富支持,允许通过分离应用的业务逻辑与系l服务Q例如审计(auditingQ和事务QtransactionQ管理)q行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们ƈ不负责(甚至是意识)其它的系lx点,例如日志或事务支持?div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; ">
  ◆容器——Spring包含q管理应用对象的配置和生命周期,在这个意义上它是一U容器,你可以配|你的每个bean如何被创?#8212;—Z一个可配置原型QprototypeQ,你的bean可以创徏一个单独的实例或者每ơ需要时都生成一个新的实?#8212;—以及(qing)它们是如何相互关联的。然而,Spring不应该被混同于传l的重量U的EJB容器Q它们经常是庞大与笨重的Q难以用?div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; ">  ◆框架——Spring可以简单的lg配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文g里。Spring也提供了很多基础功能Q事务管理、持久化框架集成{等Q,应用逻辑的开发留l了你?div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; ">  所有Spring的这些特征你能够编写更q净、更可管理、ƈ且更易于试的代码。它们也为Spring中的各种模块提供了基支持?br />
二:(x)spring的整个生命周?/strong>
    首先说一下spring的整个初始化q程Qweb应用中创建spring容器有两U方式:(x)
    W一U:(x)在web.xml里直接配|spring容器Qservletcontextlistener
    W二U:(x)通过load-on-startup servlet实现?br />    主要p一下第一U方式:(x)
    spring提供了ServletContextListener的实现类ContextLoaderListener,该类作ؓ(f)listener使用Q在创徏时自动查找W(wng)EB-INF目录下的applicationContext.xml,该文件是默认查找的,如果只有一个就不需要配|初始化xml参数Q如果需要配|,讄contextConfigLocation为application的xml文g卛_。可以好好阅M下ContextLoaderListener的源代码Q就可以很清楚的知道spring的整个加载过E?br />    spring容器的初始化代码如下Q?br />    /**
     * Initialize the root web application context.
     */
    
public void contextInitialized(ServletContextEvent event) {
        
this.contextLoader = createContextLoader();
        
if (this.contextLoader == null) {
            
this.contextLoader = this;
        }
        
this.contextLoader.initWebApplicationContext(event.getServletContext());//contextLoader初始化web应用容器

    }
    l箋分析initWebApplicationContext做了什么事情:(x)
    

    
/**
     * Initialize Spring's web application context for the given servlet context,
     * according to the "{
@link #CONTEXT_CLASS_PARAM contextClass}" and
     * "{
@link #CONFIG_LOCATION_PARAM contextConfigLocation}" context-params.
     * 
@param servletContext current servlet context
     * 
@return the new WebApplicationContext
     * 
@see #CONTEXT_CLASS_PARAM
     * 
@see #CONFIG_LOCATION_PARAM
     
*/
    
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
      
//首先创徏一个spring的父容器Q类似根节点root容器Q而且只能是一个,如果已经创徏Q抛出对应的异常
        
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
            
throw new IllegalStateException(
                    
"Cannot initialize context because there is already a root application context present - " +
                    
"check whether you have multiple ContextLoader* definitions in your web.xml!");
        }

        Log logger 
= LogFactory.getLog(ContextLoader.class);
        servletContext.log(
"Initializing Spring root WebApplicationContext");
        
if (logger.isInfoEnabled()) {
            logger.info(
"Root WebApplicationContext: initialization started");
        }
        
long startTime = System.currentTimeMillis();

        
try {
            
// Determine parent for root web application context, if any.
            ApplicationContext parent = loadParentContext(servletContext);//创徏通过web.xml配置的父容器            
具体里面的代码是怎么实现的,׃在这里进行详解了
// Store context in local instance variable, to guarantee that
            
// it is available on ServletContext shutdown.
            this.context = createWebApplicationContext(servletContext, parent);//主要的创E都在改Ҏ(gu)内,可以自己ȝ源代?/span>
            servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, 
this.context);
            
//把spring初始好的容器加蝲到servletcontext内,相当于servletcontext包含webapplicationcontext
            ClassLoader ccl 
= Thread.currentThread().getContextClassLoader();
            
if (ccl == ContextLoader.class.getClassLoader()) {
                currentContext 
= this.context;
            }
            
else if (ccl != null) {
                currentContextPerThread.put(ccl, 
this.context);
            }

            
if (logger.isDebugEnabled()) {
                logger.debug(
"Published root WebApplicationContext as ServletContext attribute with name [" +
                        WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 
+ "]");
            }
            
if (logger.isInfoEnabled()) {
                
long elapsedTime = System.currentTimeMillis() - startTime;
                logger.info(
"Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
            }

            
return this.context;
        }
        
catch (RuntimeException ex) {
            logger.error(
"Context initialization failed", ex);
            servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
            
throw ex;
        }
        
catch (Error err) {
            logger.error(
"Context initialization failed", err);
            servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
            
throw err;
        }
    }
    
    看到q里基本已经清楚了整个spring容器的加载过E,如果q想了解更加深入Q请查看我红色标注的Ҏ(gu)体?br />
    其次再说一下spring的IOC和AOP使用的场景,׃原理大家都很清楚了,那就说一下它们用到的地方:(x)
   

    IOC使用的场景:(x)
        理bean的依赖关p,目前L的电(sh)子商务网站基本都采用spring理业务层代码的依赖关系Q包?淘宝Q支付宝Q阿里巴_(d)癑ֺ{公司?br />        

陈睿 2012-02-29 14:45 发表评论
]]>
框架-struts2http://www.aygfsteel.com/mikechen/archive/2012/02/27/370857.html陈睿陈睿Mon, 27 Feb 2012 09:07:00 GMThttp://www.aygfsteel.com/mikechen/archive/2012/02/27/370857.htmlhttp://www.aygfsteel.com/mikechen/comments/370857.htmlhttp://www.aygfsteel.com/mikechen/archive/2012/02/27/370857.html#Feedback2http://www.aygfsteel.com/mikechen/comments/commentRss/370857.htmlhttp://www.aygfsteel.com/mikechen/services/trackbacks/370857.html一Qstruts2概要
    以WebWork优秀设计思想为核心,吸收了struts1的部分优炏V?br />
二:(x)struts2详解
    主要是详解struts2与struts1之间的区别,以及(qing)Z么要采用webwork重新设计新框Ӟ以及(qing)吸收了struts1的哪部分优点?br />    首先区别:(x)
  •     最大的区别是与servlet成功解耦,不在依赖容器来初始化HttpServletRequest和HttpServletResponse
    struts1里依赖的核心控制器ؓ(f)ActionServlet而struts2依赖ServletDispatcher,一个是servlet一个是filter,正是采用了filter才不至于和servlet耦合Q所有的数据 都是通过拦截器来实现Q如下图昄Q?/blockquote>    

  •     web层表现层的丰富,struts2已经可以使用jsp、velocity、freemarker
  •     U程模式斚wQstruts1的action是单例模式而且必须是线E安全或同步的,是struts2的actionҎ(gu)一个请求都产生一个新的实例,因此没有U程安全?      题?/li>
  •     装h参数Q是struts1采用ActionForm装h参数Q都必须l承ActionForm基类Q而struts2通过bean的属性封装,大大降低了耦合?/li>
  •     cd转换Qstruts1装的ActionForm都是StringcdQ采用Commons- Beanutilsq行cd转换Q每个类一个{换器Qstruts2采用OGNLq行cd?      换,支持基本数据cd和封装类型的自动转换?/li>
  •     数据校验Qstruts1在ActionForm中重写validateҎ(gu)Qstruts2直接重写validateҎ(gu)Q直接在action里面重写卛_Q不需要承Q何基c,实际的调用顺序是Qvalidate()-->execute()Q会(x)在执行execute之前调用validate,也支持xwork校验框架来校验?/li>
    其次Q讲一下ؓ(f)什么要采用webwork来重新设计struts2
          
首先的从核心控制器谈Pstruts2的FilterDispatcherQ这里我们知道是一个filter而不是一个servlet,讲到q里很多不是很清楚web.xml里它们之间的联系Q先短讲一下它们的加蝲序Qcontext-param(应用范围的初始化参数)-->listener(监听应用端的M修改通知)-->filter(qo(h))-->servlet?br />    filter在执行servlet之间׃?qing)调用了Q所以才有可能解脱完全依赖servlet的局面,那我们来看看q个filter做了什么事情:(x)
    /**
     * Process an action or handle a request a static resource.
     * <p/>
     * The filter tries to match the request to an action mapping.
     * If mapping is found, the action processes is delegated to the dispatcher's serviceAction method.
     * If action processing fails, doFilter will try to create an error page via the dispatcher.
     * <p/>
     * Otherwise, if the request is for a static resource,
     * the resource is copied directly to the response, with the appropriate caching headers set.
     * <p/>
     * If the request does not match an action mapping, or a static resource page,
     * then it passes through.
     *
     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
     
*/
    
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request 
= (HttpServletRequest) req;
        HttpServletResponse response 
= (HttpServletResponse) res;
        ServletContext servletContext 
= getServletContext();

        String timerKey 
= "FilterDispatcher_doFilter: ";
        
try {

            
// FIXME: this should be refactored better to not duplicate work with the action invocation
            ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
            ActionContext ctx 
= new ActionContext(stack.getContext());
            ActionContext.setContext(ctx);

            UtilTimerStack.push(timerKey);
            request 
= prepareDispatcherAndWrapRequest(request, response);
            ActionMapping mapping;
            
try {
                mapping 
= actionMapper.getMapping(request, dispatcher.getConfigurationManager());
            } 
catch (Exception ex) {
                log.error(
"error getting ActionMapping", ex);
                dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
                
return;
            }

            
if (mapping == null) {
                
// there is no action in this request, should we look for a static resource?
                String resourcePath = RequestUtils.getServletPath(request);

                
if ("".equals(resourcePath) && null != request.getPathInfo()) {
                    resourcePath 
= request.getPathInfo();
                }

                
if (staticResourceLoader.canHandle(resourcePath)) {
                    staticResourceLoader.findStaticResource(resourcePath, request, response);
                } 
else {
                    
// this is a normal request, let it pass through
                    chain.doFilter(request, response);
                }
                
// The framework did its job here
                return;
            }

            dispatcher.serviceAction(request, response, servletContext, mapping);
//qo(h)用户hQ拦截器执行Q把对应的actionh转到业务action执行        } 

finally {
            
try {
                ActionContextCleanUp.cleanUp(req);
            } 
finally {
                UtilTimerStack.pop(timerKey);
            }
        }
    }
    对应的action参数由拦截器获取?br />    解耦servlet是struts2采用webwork思\的最重要的一个原因,也迎合了整个技术的一个发展方向,解耦一直诏I于整个框架?/span>
        

陈睿 2012-02-27 17:07 发表评论
]]> վ֩ģ壺 ;| ̺| Ű| 㽭ʡ| ƽ| | | ۩| | | հ| ˮ| | ͤ| | | | ϲ| Ͽ| | | | | տ| | | | | ˳| | | Ӣɳ| | | | ˮ| | ·| | ƺ| |