??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲六月丁香婷婷综合,亚洲一久久久久久久久,亚洲av无码精品网站http://www.tkk7.com/junky/category/11393.htmlzh-cnThu, 23 Aug 2007 11:50:47 GMTThu, 23 Aug 2007 11:50:47 GMT60一步一步开发Spring Framework MVC应用E序(?http://www.tkk7.com/junky/archive/2007/08/22/138543.htmljunkyjunkyWed, 22 Aug 2007 02:50:00 GMThttp://www.tkk7.com/junky/archive/2007/08/22/138543.htmlhttp://www.tkk7.com/junky/comments/138543.htmlhttp://www.tkk7.com/junky/archive/2007/08/22/138543.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/138543.htmlhttp://www.tkk7.com/junky/services/trackbacks/138543.html阅读全文

junky 2007-08-22 10:50 发表评论
]]>
Spring interceptorhttp://www.tkk7.com/junky/archive/2007/06/28/126716.htmljunkyjunkyThu, 28 Jun 2007 01:36:00 GMThttp://www.tkk7.com/junky/archive/2007/06/28/126716.htmlhttp://www.tkk7.com/junky/comments/126716.htmlhttp://www.tkk7.com/junky/archive/2007/06/28/126716.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/126716.htmlhttp://www.tkk7.com/junky/services/trackbacks/126716.html1 Spring的通知cd

现在让我们看?span>Spring AOP是如何处理通知的?/span>

1.1. 通知的生命周?/span>

Spring的通知可以跨越多个被通知对象׃nQ或者每个被通知对象有自q通知。这分别对应 per-class?em>per-instance 通知?/span>

Per-class通知使用最为广泛。它适合于通用的通知Q如事务adisor。它们不依赖被代?的对象的状态,也不d新的状态。它们仅仅作用于Ҏ和方法的参数?/span>

Per-instance通知适合于导入,来支持؜入(mixinQ。在q种情况下,通知d状态到 被代理的对象?/span>

可以在同一?span>AOP代理中؜合用共享和per-instance通知?/span>

1.2. Spring中通知cd

Spring提供几种现成的通知cdq可扩展提供L的通知cd。让我们看看基本概念和标准的通知cd?/span>

1.2.1. Interception around advice

Spring中最基本的通知cd?em>interception around advice .

Spring使用Ҏ拦截器的around通知是和AOP联盟接口兼容的。实?span>around通知?c需要实现接?span>MethodInterceptorQ?/span>

public interface MethodInterceptor extends Interceptor {

 

    Object invoke(MethodInvocation invocation) throws Throwable;

}

invoke()Ҏ?em>MethodInvocation 参数暴露被调用的方法、目标连接点?span>AOP代理和传递给被调用方法的参数?invoke()Ҏ应该q回调用的结果:q接点的q回倹{?/span>

一个简单的MethodInterceptor实现看v来如?span>:

public class DebugInterceptor implements MethodInterceptor {

 

    public Object invoke(MethodInvocation invocation) throws Throwable {

        System.out.println("Before: invocation=[" + invocation + "]");

        Object rval = invocation.proceed();

        System.out.println("Invocation returned");

        return rval;

    }

}

注意MethodInvocation?em>proceed()Ҏ的调用。这个调用会应用到目标连接点的拦截器链中的每一个拦截器。大部分拦截器会调用q个ҎQƈq回它的q回倹{但是, 一?span>MethodInterceptorQ和Maround通知一P可以q回不同的值或者抛Z个异常,?不调?span>proceedҎ。但是,没有好的原因你要q么做?/span>

MethodInterceptor提供了和其他AOP联盟的兼容实现的交互能力。这一节下?要讨论的其他的通知cd实现?span>AOP公共的概念,但是?span>Spring特定的方式。虽然用特?通知cd有很多优点,但如果你可能需要在其他?span>AOP框架中用,请坚持?span>MethodInterceptor around通知cd。注意目前切入点不能和其它框架交互操作,q且AOP联盟目前也没有定义切?Ҏ口?/span>

1.2.2. Before通知

Before通知是一U简单的通知cd?q个通知不需要一?span>MethodInvocation对象Q因为它只在q入一个方法前被调用?/span>

Before通知的主要优Ҏ它不需要调?span>proceed() ҎQ?因此没有无意中忘掉l执行拦截器铄可能性?/span>

MethodBeforeAdvice接口如下所C?span> (Spring?span>API设计允许成员变量?span>before通知Q虽然一般的对象都可以应用成员变量拦截,?span>Spring 有可能永q不会实现它Q?/span>

public interface MethodBeforeAdvice extends BeforeAdvice {

 

    void before(Method m, Object[] args, Object target) throws Throwable;

}

注意q回cd?span>void?span> Before通知可以在连接点执行之前 插入自定义的行ؓQ但是不能改变返回倹{如果一?span>before通知抛出一个异常,q将中断拦截?铄q一步执行。这个异常将沿着拦截器链后退着向上传播。如果这个异常是unchecked的,或?出现在被调用的方法的{֐中,它将会被直接传递给客户代码Q否则,它将?span>AOP代理包装C?span>unchecked 的异帔R?/span>

下面?span>Spring中一?span>before通知的例子,q个例子计数所有正常返回的ҎQ?/span>

public class CountingBeforeAdvice implements MethodBeforeAdvice {

    private int count;

    public void before(Method m, Object[] args, Object target) throws Throwable {

        ++count;

    }

 

    public int getCount() {

        return count;

    }

}

Before通知可以被用于Q何类型的切入炏V?/span>

1.2.3. Throws通知

如果q接Ҏ出异常,Throws通知 在连接点q回后被调用?span>Spring提供强类型的throws通知。注意这意味着 org.springframework.aop.ThrowsAdvice接口不包含Q何方法: 它是一个标记接口,标识l定的对象实C一个或多个强类型的throws通知Ҏ。这些方法Ş?如下Q?/span>

afterThrowing([Method], [args], [target], subclassOfThrowable)

只有最后一个参数是必需的。这样从一个参数到四个参数Q依赖于通知是否Ҏ法和Ҏ 的参数感兴趣。下面是throws通知的例子?/span>

如果抛出RemoteException异常Q包括子c), q个通知会被调用

public class RemoteThrowsAdvice implements ThrowsAdvice {

 

    public void afterThrowing(RemoteException ex) throws Throwable {

        // Do something with remote exception

    }

}

如果抛出ServletException异常Q?下面的通知会被调用。和上面的通知不一P它声明了四个参数Q所以它可以讉K被调用的ҎQ方法的参数和目标对?span>:

public static class ServletThrowsAdviceWithArguments implements ThrowsAdvice {

 

    public void afterThrowing(Method m, Object[] args, Object target, ServletException ex) {

        // Do something will all arguments

    }

}

最后一个例子演CZ如何在一个类中用两个方法来同时处理 RemoteException?span>ServletException 异常。Q意个数的throwsҎ可以被组合在一个类中?/span>

public static class CombinedThrowsAdvice implements ThrowsAdvice {

 

    public void afterThrowing(RemoteException ex) throws Throwable {

        // Do something with remote exception

    }

 

    public void afterThrowing(Method m, Object[] args, Object target, ServletException ex) {

        // Do something will all arguments

    }

}

Throws通知可被用于Mcd的切入点?/span>

1.2.4. After Returning通知

Spring中的after returning通知必须实现 org.springframework.aop.AfterReturningAdvice 接口Q如下所C:

public interface AfterReturningAdvice extends Advice {

 

    void afterReturning(Object returnValue, Method m, Object[] args, Object target)

            throws Throwable;

}

After returning通知可以讉Kq回|不能改变Q、被调用的方法、方法的参数和目标对象?/span>

下面?span>after returning通知l计所有成功的没有抛出异常的方法调用:

public class CountingAfterReturningAdvice implements AfterReturningAdvice {

    private int count;

 

    public void afterReturning(Object returnValue, Method m, Object[] args, Object target) throws Throwable {

        ++count;

    }

 

    public int getCount() {

        return count;

    }

}

q方法不改变执行路径。如果它抛出一个异常,q个异常而不是返回值将被沿着拦截器链向上抛出?/span>

After returning通知可被用于Mcd的切入点?/span>

1.2.5. Introduction通知

Spring?span>introduction通知看作一U特D类型的拦截通知?/span>

Introduction需要实?span>IntroductionAdvisor, ?span>IntroductionInterceptor接口Q?/span>

public interface IntroductionInterceptor extends MethodInterceptor {

 

    boolean implementsInterface(Class intf);

}

l承?span>AOP联盟MethodInterceptor接口?span> invoke()Ҏ必须实现导入Q也是_如果被调用的Ҏ是在 导入的接口中Q导入拦截器负责处理q个Ҏ调用Q它不能调用proceed() Ҏ?/span>

Introduction通知不能被用于Q何切入点Q因为它只能作用于类层次上,而不是方法。你可以只用InterceptionIntroductionAdvisor来实现导入通知Q它有下面的ҎQ?/span>

public interface InterceptionIntroductionAdvisor extends InterceptionAdvisor {

 

    ClassFilter getClassFilter();

 

    IntroductionInterceptor getIntroductionInterceptor();

 

    Class[] getInterfaces();

}

q里没有MethodMatcherQ因此也没有和导入通知兌?切入炏V只有类qo是合乎逻辑的?/span>

getInterfaces()Ҏq回advisor导入的接口?/span>

让我们看看一个来?span>Spring试套g中的单例子。我们假设想要导入下面的接口C?或者多个对象中:

public interface Lockable {

    void lock();

    void unlock();

    boolean locked();

}

q个例子演示了一?span>mixin。我们想要能?被通知对象cd转换?span>LockableQ不它们的cdQƈ且调?span>lock?span>unlockҎ。如果我们调?span> lock()ҎQ我们希望所?span>setterҎ抛出LockedException异常。这h们能d一个方面的对象不可变Q而它们不需要知道这一点:q是一个很好的AOP?子?/span>

首先Q我们需要一个做大量转化?span>IntroductionInterceptor?在这里,我们l承 org.springframework.aop.support.DelegatingIntroductionInterceptor 实用cR我们可以直接实?span>IntroductionInterceptor接口Q但是大多数情况?span> DelegatingIntroductionInterceptor是最合适的?/span>

DelegatingIntroductionInterceptor的设计是导?委托到真正实现导入接口的接口Q隐藏完成这些工作的拦截器。委托可以用构造方法参?讄CQ何对象中Q默认的委托是自己Q当无参数的构造方法被使用Ӟ。这样在下面的例子里Q委托是DelegatingIntroductionInterceptor的子c?span> LockMixin。给定一个委托(默认是自w)?span> DelegatingIntroductionInterceptor实例L被这个委托(而不 ?span>IntroductionInterceptorQ实现的所有接口,q支持它们中M一个导入。子cd LockMixin也可能调?span>suppressInterflace(Class intf) Ҏ隐藏不应暴露的接口。然而,不管IntroductionInterceptor 准备支持多少接口Q?span>IntroductionAdvisor控制哪个接口将被实?暴露。一个导入的接口隐藏目标的同一个接口的所有实现?/span>

q样Q?span>LockMixinl承DelegatingIntroductionInterceptor q自己实?span>Lockable。父c自动选择支持导入?span>LockableQ所以我们不需要指定它。用q种Ҏ我们可以导入L数量的接口?/span>

注意locked实例变量的用。这有效地添加额外的状态到目标 对象?/span>

public class LockMixin extends DelegatingIntroductionInterceptor

    implements Lockable {

 

    private boolean locked;

 

    public void lock() {

        this.locked = true;

    }

 

    public void unlock() {

        this.locked = false;

    }

 

    public boolean locked() {

        return this.locked;

    }

 

    public Object invoke(MethodInvocation invocation) throws Throwable {

        if (locked() && invocation.getMethod().getName().indexOf("set") == 0)

            throw new LockedException();

        return super.invoke(invocation);

    }

 

}

通常不要需要改?span>invoke()ҎQ实?span> DelegatingIntroductionInterceptorp够了Q如果是导入的方法, DelegatingIntroductionInterceptor实现会调用委托方法, 否则l箋沿着q接点处理。在现在的情况下Q我们需要添加一个检查:在上锁状态下不能调用setterҎ?/span>

所需的导?span>advisor是很单的。只有保存一个独立的 LockMixin实例Qƈ指定导入的接口,在这里就?span> Lockable。一个稍微复杂一点例子可能需要一个导入拦截器Q可?定义?span>prototypeQ的引用Q在q种情况下,LockMixin没有相关配置Q所以我们简单地 使用new来创建它?/span>

public class LockMixinAdvisor extends DefaultIntroductionAdvisor {

 

    public LockMixinAdvisor() {

        super(new LockMixin(), Lockable.class);

    }

}

我们可以非常单地使用q个advisorQ它不需要Q何配|。(但是Q有一??/em>必要的:是不可能在没有IntroductionAdvisor 的情况下使用IntroductionInterceptor。) 和导入一P通常 advisor必须是针Ҏ个实例的Qƈ且是有状态的。我们会有不同的?span>LockMixinAdvisor 每个被通知对象Q会有不同的LockMixin?span> advisorl成了被通知对象的状态的一部分?/span>

和其?span>advisor一P我们可以使用 Advised.addAdvisor() Ҏ以编E地方式使用q种advisorQ或者在XML中配|(推荐q种方式Q?下面讨论所有代理创建,包括自动代理创徏?span>”Q选择代理创徏以正地处理导入和有状态的混入?/span>

 

 

参考资料:

1Q?/font> http://www.javaresearch.org/article/showarticle.jsp?column=23&thread=41315

2Q?/font> http://tech.ccidnet.com/art/1112/20051114/371959_5.html

3Q?/font> http://www.7dspace.com/doc/21/0603/20063305365394884.htm

4Q?/font> http://barton131420.cnblogs.com/articles/280664.html

5Q?/font> http://www.opentown.info/bbs/viewtopic.php?t=7

 



junky 2007-06-28 09:36 发表评论
]]>
Spring ~程入门十大问题解答http://www.tkk7.com/junky/archive/2007/06/07/122540.htmljunkyjunkyThu, 07 Jun 2007 03:10:00 GMThttp://www.tkk7.com/junky/archive/2007/06/07/122540.htmlhttp://www.tkk7.com/junky/comments/122540.htmlhttp://www.tkk7.com/junky/archive/2007/06/07/122540.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/122540.htmlhttp://www.tkk7.com/junky/services/trackbacks/122540.html
  你可以通过下列途径学习springQ?br>
  (1) spring下蝲包中doc目录下的MVC-step-by-step和sample目录下的例子都是比较好的spring开发的例子?

  (2) AppFuse集成了目前最行的几个开源轻量框架或者工?Ant,XDoclet,Spring,Hibernate(iBATIS),JUnit,Cactus,StrutsTestCase,Canoo's WebTest,Struts Menu,Display Tag Library,OSCache,JSTL,Struts ?br>
  你可以通过AppFuse源代码来学习spring?br>
AppFuse|站Qhttp://raibledesigns.com/wiki/Wiki.jsp?page=AppFuse

  (3)Spring 开发指?夏昕)Qhttp://www.xiaxin.net/Spring_Dev_Guide.rarQ?br>
  一本spring的入门书c?里面介绍了反转控制和依赖注射的概念,以及spring的bean理Qspring的MVCQspring和hibernteQiBatis的结合?br>
  (4) spring学习的中文论?br>
  SpringFramework中文论坛(http://spring.jactiongroup.net)

  Java视线论坛(http://forum.javaeye.com)的spring栏目

  2、利用Spring框架~程Qconsole打印出log4j:WARN Please initialize the log4j system properlyQ?br>
  说明你的log4j.properties没有配置。请把log4j.properties攑ֈ工程的classpath中,eclipse的classpath为bin目录Q由于编译后src目录下的文g会拷贝到bin目录下,所以你可以把log4j.properties攑ֈsrc目录下?br>
  q里l出一个log4j.properties的例子:

log4j.rootLogger=DEBUG,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %5p (%F:%L) - %m%n

  3、出?java.lang.NoClassDefFoundError?

  一般情况下是由于你没有把必要的jar包放到lib中?br>
  比如你要采用spring和hibernateQ带事务支持的话Q,你除了spring.jar外还需要hibernat.jar、aopalliance.jar、cglig.jar、jakarta-commons下的几个jar包?br>
http://www.springframework.org/download.html下蝲spring开发包Q提供两Uzip?br>spring-framework-1.1.3-with-dependencies.zip和spring-framework-1.1.3.zipQ我你下载spring-framework-1.1.3-with-dependencies.zip。这个zip解压~后比后者多一个lib目录Q其中有hibernate、j2ee、dom4j、aopalliance、jakarta-commons{常用包?br>
  4、java.io.FileNotFoundException: Could not open class path resource [....hbm.xml],提示找不到xml文gQ?br>
  原因一般有两个Q?br>
  (1)该xml文g没有在classpath中?

  (2)applicationContext-hibernate.xml中的xml名字没有带包名。比如:

Qbean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"Q?br>Qproperty name="dataSource"Q<ref bean="dataSource"/Q</propertyQ?br>Qproperty name="mappingResources"Q?br> QlistQ?br>  QvalueQUser.hbm.xmlQ?valueQ?br>  错,改ؓQ?
  QvalueQcom/yz/spring/domain/User.hbm.xmlQ?valueQ?br> Q?listQ?br>Q?propertyQ?br>Qproperty name="hibernateProperties"Q?br>QpropsQ?
 Qprop key="hibernate.dialect"Q?net.sf.hibernate.dialect.MySQLDialect Q?propQ?
 Qprop key="hibernate.show_sql"QtrueQ?propQ?
Q?propsQ?
Q?propertyQ?br>Q?beanQ?/td>

  5、org.springframework.beans.NotWritablePropertyException: Invalid property 'postDao' of bean classQ?br>
  出现异常的原因是在application-xxx.xml中property name的错误?br>
  Qproperty name="...."Q?中name的名字是与bean的setҎ相关的,而且要注意大写?br>
  比如

public class PostManageImpl extends BaseManage implements PostManage {
 private PostDAO dao = null;
 public void setPostDAO(PostDAO postDAO){
  this.dao = postDAO;
 }
}

  那么xml的定义应该是Q?br>
Qbean id="postManage" parent="txProxyTemplate"Q?br>Qproperty name="target"Q?br> Qbean class="com.yz.spring.service.implement.PostManageImpl"Q?br>  Qproperty name="postDAO"Q<ref bean="postDAO"/Q</propertyQ??br>  Qproperty name="dao"Q<ref bean="postDAO"/Q</propertyQ??br> Q?beanQ?br>Q?propertyQ?br>Q?beanQ?/td>

  6、Spring中如何实C务管理?

  首先Q如果用mysqlQ确定mysql为InnoDBcd?br>
  事务理的控制应该放到商业逻辑层。你可以写个处理商业逻辑的JavaBeanQ在该JavaBean中调用DAOQ然后把该Bean的方法纳入spring的事务管理?br>
  比如Qxml文g定义如下Q?br>
Qbean id="txProxyTemplate" abstract="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"Q?br>Qproperty name="transactionManager"Q<ref bean="transactionManager"/Q</propertyQ?br>Qproperty name="transactionAttributes"Q?br>QpropsQ?br>Qprop key="save*"QPROPAGATION_REQUIREDQ?propQ?br>Qprop key="remove*"QPROPAGATION_REQUIREDQ?propQ?br>Qprop key="*"QPROPAGATION_REQUIREDQ?propQ?br>Q?propsQ?br>Q?propertyQ?br>Q?beanQ?br>
Qbean id="userManage" parent="txProxyTemplate"Q?br> Qproperty name="target"Q?br>  Qbean class="com.yz.spring.service.implement.UserManageImpl"Q?br>   Qproperty name="userDAO"Q<ref bean="userDAO"/Q</propertyQ?br>  Q?beanQ?br> Q?propertyQ?br>Q?beanQ?/td>

  com.yz.spring.service.implement.UserManageImpl是我们的实现商业逻辑的JavaBean。我们通过parent元素声明其事务支持?br>
  7、如何管理Spring框架下更多的JavaBeanQ?br>
  JavaBean多Qspring配置文gp大,q样不易l护。ؓ了配置清晰Q我们可以将JavaBean分类理Q放在不同的配置文g中?应用启动时将所有的xml同时加蝲?br>
  比如Q?br>
  DAO层的JavaBean攑ֈapplicationContext-hibernate.xml中,商业逻辑层的JavaBean攑ֈapplicationContext-service.xml中。然后启动类中调用以下代码蝲入所有的ApplicationContext?br>
String[] paths = {"com/yz/spring/dao/hibernate/applicationContext-hibernate.xml",
"com/yz/spring/service/applicationContext-service.xml"};
ctx = new ClassPathXmlApplicationContext(paths);

  8、web应用中如何加载ApplicationContextQ?br>
  可以通过定义web.xmlQ由web容器自动加蝲?br>
QservletQ?br>Qservlet-nameQcontextQ?servlet-nameQ?br>Qservlet-classQorg.springframework.web.context.ContextLoaderServletQ?servlet-classQ?br>Qload-on-startupQ?Q?load-on-startupQ?br>Q?servletQ?br>
Qcontext-paramQ?br>Qparam-nameQcontextConfigLocationQ?param-nameQ?br>Qparam-valueQ?WEB-INF/applicationContext-hibernate.xmlQ?param-valueQ?br>Qparam-valueQ?WEB-INF/applicationContext-service.xmlQ?param-valueQ?br>Q?context-paramQ?/td>

  9、在spring中如何配|的log4j?

  在web.xml中加入以下代码即可?br>
Qcontext-paramQ?br>Qparam-nameQlog4jConfigLocationQ?param-nameQ?br>Qparam-valueQ?WEB-INF/log4j.propertiesQ?param-valueQ?br>Q?context-paramQ?/td>

  10、Spring框架入门的编E问题解决了Q我该如何更深地领会Spring框架呢?

  q两本书你该ȝ看。这两本书是由Spring的作者Rod Johnson~写的?br>
Expert One on one J2EE Design and Development
Expert One on one J2EE Development Without EJB

  你也该看看martinfowler的Inversion of Control Containers and the Dependency Injection pattern?br>
http://www.martinfowler.com/articles/injection.html
 
  再好好研M下spring的文?br>
http://www.jactiongroup.net/reference/html/index.htmlQ中文版Q未全部译Q?/td>

  q有是多实践吧?

junky 2007-06-07 11:10 发表评论
]]>
Open Session In View探讨(?http://www.tkk7.com/junky/archive/2007/03/06/102142.htmljunkyjunkyTue, 06 Mar 2007 06:01:00 GMThttp://www.tkk7.com/junky/archive/2007/03/06/102142.htmlhttp://www.tkk7.com/junky/comments/102142.htmlhttp://www.tkk7.com/junky/archive/2007/03/06/102142.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/102142.htmlhttp://www.tkk7.com/junky/services/trackbacks/102142.html 在没有?/font> Spring 提供?/span> Open Session In View 情况下,因需要在 service(or Dao) 层里?/span> session 关闭Q所?/span> lazy loading ?/span> true 的话Q要在应用层内把关系集合都初始化Q如 company.getEmployees() Q否?/span> Hibernate ?/span> session already closed Exception;     Open Session In View 提供了一U简便的ҎQ较好地解决?/span> lazy loading 问题 .

    它有两种配置方式OpenSessionInViewInterceptor ?span style="FONT-SIZE: 10pt; COLOR: #4b4b4b; FONT-FAMILY: Verdana">OpenSessionInViewFilter(具体参看SpringSide) Q功能相同,只是一个在 web.xml 配置Q另一个在 application.xml 配置而已?/span>

    Open Session In View ?/span> request ?/span> session l定到当?/span> thread 期间一直保?/span> hibernate session ?/span> open 状态,?/span> session ?/span> request 的整个期间都可以使用Q如?/span> View 层里 PO 也可?/span> lazy loading 数据Q如 ${ company.employees } 。当 View 层逻辑完成后,才会通过 Filter ?/span> doFilter Ҏ?/span> Interceptor ?/span> postHandle Ҏ自动关闭 session ?/span>


										
OpenSessionInViewInterceptor配置
  1. <beans>
  2. <bean name="openSessionInViewInterceptor"
  3. class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
  4. <property name="sessionFactory">
  5. <ref bean="sessionFactory"/>
  6. </property>
  7. </bean>
  8. <bean id="urlMapping"
  9. class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  10. <property name="interceptors">
  11. <list>
  12. <ref bean="openSessionInViewInterceptor"/>
  13. </list>
  14. </property>
  15. <property name="mappings">
  16. ...
  17. </property>
  18. </bean>
  19. ...
  20. </beans>
										
OpenSessionInViewFilter配置
  1. <web-app>
  2. ...
  3. <filter>
  4. <filter-name>hibernateFilter</filter-name>
  5. <filter-class>
  6. org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
  7. </filter-class>
  8. <!-- singleSession默认为true,若设为false则等于没?span class="me1">OpenSessionInView -->
  9. <init-param>
  10. <param-name>singleSession</param-name>
  11. <param-value>true</param-value>
  12. </init-param>
  13. </filter>
  14. ...
  15. <filter-mapping>
  16. <filter-name>hibernateFilter</filter-name>
  17. <url-pattern>*.do</url-pattern>
  18. </filter-mapping>
  19. ...
  20. </web-app>

很多人在使用OpenSessionInViewq程中提及一个错误:

										
  1. org.springframework.dao.InvalidDataAccessApiUsageException: Write operations
  2. are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into
  3. FlushMode.AUTO or remove 'readOnly' marker from transaction definition

看看OpenSessionInViewFilter里的几个Ҏ

										
  1. protected void doFilterInternal(HttpServletRequest request,
    HttpServletResponse response,FilterChain filterChain)
    throws ServletException, IOException{
     SessionFactory sessionFactory = lookupSessionFactory();
     logger.debug("Opening Hibernate Session in OpenSessionInViewFilter");
     Session session = getSession(sessionFactory);
     TransactionSynchronizationManager.bindResource(
      sessionFactory, new SessionHolder(session));
     try{
      filterChain.doFilter(request, response);
     }
     finally{
     TransactionSynchronizationManager.unbindResource(sessionFactory);
     logger.debug("Closing Hibernate Session in OpenSessionInViewFilter");
     closeSession(session, sessionFactory);
     }
    }




     
  2. protected Session getSession(SessionFactory sessionFactory)
    throws DataAccessResourceFailureException {
     Session session = SessionFactoryUtils.getSession(sessionFactory, true);
     session.setFlushMode(FlushMode.NEVER);
     return session;
    }

  3. protected
    void closeSession(Session session, SessionFactory sessionFactory)
    throws CleanupFailureDataAccessException {
     SessionFactoryUtils.closeSessionIfNecessary(session, sessionFactory);
    }

     可以看到OpenSessionInViewFilter在getSession的时?会把获取回来的session的flush mode 设ؓFlushMode.NEVER。然后把该sessionFactoryl定到TransactionSynchronizationManagerQrequest的整个过E都使用同一个sessionQ在hq后再接除该sessionFactory的绑定,最?span class="me1">closeSessionIfNecessaryҎ该session是否已和transactionl定来决定是否关闭session。在q个q程中,若HibernateTemplate 发现自当前session有不是readOnly的transactionQ就会获取到FlushMode.AUTO SessionQҎ拥有写权限?/p>

										
  1. public static void closeSessionIfNecessary(Session session, SessionFactory sessionFactory)
  2. throws CleanupFailureDataAccessException {
  3. if (session == null ||
    TransactionSynchronizationManager.hasResource(sessionFactory)){
  4. return;
  5. }
  6. logger.debug("Closing Hibernate session");
  7. try {
  8. session.close();
  9. }
  10. catch (JDBCException ex){
  11. // SQLException underneath
  12. throw new CleanupFailureDataAccessException("Could not close Hibernate session", ex.getSQLException());
  13. }
  14. catch (HibernateException ex){
  15. throw new CleanupFailureDataAccessException("Could not close Hibernate session", ex);
  16. }
  17. }

    也即是,如果有不是readOnly的transaction可以由Flush.NEVER转ؓFlush.AUTO,拥有insert,update,delete操作权限Q如果没有transactionQƈ且没有另外h为地设flush model的话Q则doFilter的整个过E都是Flush.NEVER。所以受transaction保护的方法有写权限,没受保护的则没有?/p>

										
采用spring的事务声?使方法受transaction控制
  1.   <bean id="baseTransaction"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
              abstract="true">
            <property name="transactionManager" ref="transactionManager"/>
            <property name="proxyTargetClass" value="true"/>
            <property name="transactionAttributes">
                <props>
                    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
                    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                    <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
                    <prop key="save*">PROPAGATION_REQUIRED</prop>
                    <prop key="add*">PROPAGATION_REQUIRED</prop>
                    <prop key="update*">PROPAGATION_REQUIRED</prop>
                    <prop key="remove*">PROPAGATION_REQUIRED</prop>
                </props>
            </property>
        </bean>

  2.     <bean id="userService" parent="baseTransaction">
            <property name="target">
                <bean class="com.phopesoft.security.service.impl.UserServiceImpl"/>
            </property>
        </bean>

对于上例Q则以save,add,update,remove开头的Ҏ拥有可写的事务,如果当前有某个方法,如命名ؓimportExcel()Q则因没有transaction而没有写权限Q这时若Ҏ内有insert,update,delete操作的话Q则需要手动设|flush model为Flush.AUTO,?/p>

								
  1. session.setFlushMode(FlushMode.AUTO);
  2. session.save(user);
  3. session.flush();

     管Open Session In View看v来还不错Q其实副作用不少。看回上面OpenSessionInViewFilter的doFilterInternalҎ代码Q这个方法实际上是被父类的doFilter调用的,因此Q我们可以大U了解的OpenSessionInViewFilter调用程: request(h)->open sessionq开始transaction->controller->View(Jsp)->l束transactionqclose session.

     一切看h很正,其是在本地开发测试的时候没出现问题Q但试想下如果流E中的某一步被d的话Q那在这期间connection׃直被占用而不释放。最有可能被d的就是在写Jspq步Q一斚w可能是页面内容大Qresponse.write的时间长Q另一斚w可能是网速慢Q服务器与用户间传输旉久。当大量q样的情况出现时Q就有连接池q接不Q造成面假死现象?/p>

Open Session In View是个双刃剑,攑֜公网上内容多量大的|站h用?/p>

junky 2007-03-06 14:01 发表评论
]]>
Spring + Quartz L搞定webd定时调度(?http://www.tkk7.com/junky/archive/2007/02/25/100617.htmljunkyjunkySun, 25 Feb 2007 09:46:00 GMThttp://www.tkk7.com/junky/archive/2007/02/25/100617.htmlhttp://www.tkk7.com/junky/comments/100617.htmlhttp://www.tkk7.com/junky/archive/2007/02/25/100617.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/100617.htmlhttp://www.tkk7.com/junky/services/trackbacks/100617.htmlwebd定时调度具体的实现方法很?

q里只分n自己的唯一l验? spring + quartz.

其实spring对quartz装的完无?哈哈

试牛刀开始了...

java代码呢就是区区几?


import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.apache.log4j.*;

public class ContentArbitrateServiceJob extends QuartzJobBean {
 public static Logger log = Logger.getLogger(ContentArbitrateServiceJob.class);
 private int timeout;
 public void setTimeout(int timeout){
  this.timeout = timeout;
 }
 protected void executeInternal(JobExecutionContext arg0)
   throws JobExecutionException {
  // TODO Auto-generated method stub
  try{
   log.info("pȝ监督仲裁处理d开?gt;........");
   //业务逻辑代码调用
   log.info("pȝ监督仲裁处理dl束!");
  }catch(Exception e){
   log.error("pȝ监督仲裁处理d出现异常",e);
  }
 }

 

下面是看配|文仉面的道道?其实也不?

<bean name="contentarbitrateservicejob"  class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass">
     <value>com.xuedu.ContentArbitrateServiceJob</value>
    </property>
    <property name="jobDataAsMap">
     <map>
      <entry key="timeout">
       <value>5</value>
      </entry>
     </map>
    </property>
   </bean>
 
  <!-- 配置触发?-->
       <bean id="cronTriggerCA" class="org.springframework.scheduling.quartz.CronTriggerBean">

  <property name="jobDetail">
   <ref bean="contentarbitrateservicejob"/>
  </property>
  <!-- 每天?点到21??0分钟触发Q具体说明见附录 -->
  <property name="cronExpression">
   <value>0 50 08-21 * * ?</value>
  </property>

    </bean>
   
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

  <!-- d触发?-->
   <property name="triggers">
    <list>
   <ref local="cronTriggerCA"/>
    </list>
   </property>
    </bean>

也很单吧.

至于cronExpresession的设定格式呢,弟附下:

字段 允许?允许的特D字W?
U?0-59 , - * /
?0-59 , - * /
时 0-23 , - * /
日期 1-31 , - * ? / L W C
月䆾 1-12 或?JAN-DEC , - * /
星期 1-7 或?SUN-SAT , - * ? / L C #
q_可选) 留空, 1970-2099 , - * /


表达?意义
"0 0 12 * * ?" 每天中午12点触?
"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触发

至于每个W号 看看例子好?很简单了.



junky 2007-02-25 17:46 发表评论
]]>
Acegi安全pȝ的配|??http://www.tkk7.com/junky/archive/2007/01/30/96724.htmljunkyjunkyTue, 30 Jan 2007 06:14:00 GMThttp://www.tkk7.com/junky/archive/2007/01/30/96724.htmlhttp://www.tkk7.com/junky/comments/96724.htmlhttp://www.tkk7.com/junky/archive/2007/01/30/96724.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/96724.htmlhttp://www.tkk7.com/junky/services/trackbacks/96724.html

Acegi 的配|看h非常复杂,但事实上在实际项目的安全应用中我们ƈ不需要那么多功能,清楚的了解Acegi配置中各的功能Q有助于我们灉|的运用Acegi于实践中。?/font>

 

            Acegi 的配|看h非常复杂,但事实上在实际项目的安全应用中我们ƈ不需要那么多功能,清楚的了解Acegi配置中各的功能Q有助于我们灉|的运用Acegi于实践中?/font>

2.1 在Web.xml中的配置

1)  FilterToBeanProxy
  Acegi通过实现了Filter接口的FilterToBeanProxy提供一U特D的使用Servlet Filter的方式,它委托Spring中的Bean -- FilterChainProxy来完成过滤功能,q好处是化了web.xml的配|,q且充分利用了Spring IOC的优ѝFilterChainProxy包含了处理认证过E的filter列表Q每个filter都有各自的功能?/font>

						    <filter>
        <filter-name>Acegi Filter Chain Proxy</filter-name>
        <filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
        <init-param>
            <param-name>targetClass</param-name>
            <param-value>org.acegisecurity.util.FilterChainProxy</param-value>
        </init-param>
    </filter>

2) filter-mapping
  <filter-mapping>限定了FilterToBeanProxy的URL匚w模式,只有*.do?.jsp?j_acegi_security_check 的请求才会受到权限控Ӟ对javascript,css{不限制?/font>

						   <filter-mapping>
      <filter-name>Acegi Filter Chain Proxy</filter-name>
      <url-pattern>*.do</url-pattern>
    </filter-mapping>
    
    <filter-mapping>
      <filter-name>Acegi Filter Chain Proxy</filter-name>
      <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    
    <filter-mapping>
      <filter-name>Acegi Filter Chain Proxy</filter-name>
      <url-pattern>/j_acegi_security_check</url-pattern>
    </filter-mapping>

3) HttpSessionEventPublisher
  <listener>的HttpSessionEventPublisher用于发布HttpSessionApplicationEvents和HttpSessionDestroyedEvent事glspring的applicationcontext?/font>

						    <listener>
        <listener-class>org.acegisecurity.ui.session.HttpSessionEventPublisher</listener-class>
    </listener>


2.2 在applicationContext-acegi-security.xml?/font>

2.2.1 FILTER CHAIN

  FilterChainProxy会按序来调用这些filter,使这些filter能n用Spring ioc的功? CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON定义了url比较前先转ؓ写Q PATTERN_TYPE_APACHE_ANT定义了用Apache ant的匹配模式?/font>

						    <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
        <property name="filterInvocationDefinitionSource">
            <value>
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                PATTERN_TYPE_APACHE_ANT
               /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,
basicProcessingFilter,rememberMeProcessingFilter,anonymousProcessingFilter,
 exceptionTranslationFilter,filterInvocationInterceptor
            </value>
        </property>
    </bean>

2.2.2 基础认证

1) authenticationManager
  起到认证理的作用,它将验证的功能委托给多个ProviderQƈ通过遍历Providers, 以保证获取不同来源的w䆾认证Q若某个Provider能成功确认当前用Lw䆾Qauthenticate()Ҏ会返回一个完整的包含用户授权信息的Authentication对象Q否则会抛出一个AuthenticationException?br />Acegi提供了不同的AuthenticationProvider的实?如:
        DaoAuthenticationProvider 从数据库中读取用户信息验证n?br />        AnonymousAuthenticationProvider 匿名用户w䆾认证
        RememberMeAuthenticationProvider 已存cookie中的用户信息w䆾认证
        AuthByAdapterProvider 使用容器的适配器验证n?br />        CasAuthenticationProvider ҎYale中心认证服务验证w䆾, 用于实现单点登陆
        JaasAuthenticationProvider 从JASS登陆配置中获取用户信息验证n?br />        RemoteAuthenticationProvider Ҏq程服务验证用户w䆾
        RunAsImplAuthenticationProvider 对n份已被管理器替换的用戯行验?br />        X509AuthenticationProvider 从X509认证中获取用户信息验证n?br />        TestingAuthenticationProvider 单元试时?/font>

        每个认证者会对自己指定的证明信息q行认证Q如DaoAuthenticationProvider仅对UsernamePasswordAuthenticationTokenq个证明信息q行认证?/font>

						<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
        <property name="providers">
            <list>
                <ref local="daoAuthenticationProvider"/>
                <ref local="anonymousAuthenticationProvider"/>
                <ref local="rememberMeAuthenticationProvider"/>
            </list>
        </property>
</bean>


2) daoAuthenticationProvider
  q行单的Z数据库的w䆾验证。DaoAuthenticationProvider获取数据库中的̎号密码ƈq行匚wQ若成功则在通过用户w䆾的同时返回一个包含授权信息的Authentication对象Q否则n份验证失败,抛出一个AuthenticatiionException?/font>

						    <bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
        <property name="userDetailsService" ref="jdbcDaoImpl"/>
        <property name="userCache" ref="userCache"/>
        <property name="passwordEncoder" ref="passwordEncoder"/>
   </bean>


3) passwordEncoder 
  使用加密器对用户输入的明文进行加密。Acegi提供了三U加密器:
PlaintextPasswordEncoder—默认,不加密,q回明文.
ShaPasswordEncoder—哈希算?SHA)加密
Md5PasswordEncoder—消息摘?MD5)加密

						<bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.Md5PasswordEncoder"/>
				


4) jdbcDaoImpl 
  用于在数据中获取用户信息。 acegi提供了用户及授权的表l构Q但是您也可以自己来实现。通过usersByUsernameQueryq个SQL得到你的(用户ID,密码,状态信?;通过authoritiesByUsernameQueryq个SQL得到你的(用户ID,授权信息)

						 
<bean id="jdbcDaoImpl" 
class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
         <property name="dataSource"  ref="dataSource"/>
        <property  name="usersByUsernameQuery">
             <value>select loginid,passwd,1 from users where loginid =  ?</value>
         </property>
        <property  name="authoritiesByUsernameQuery">
             <value>select u.loginid,p.name from users u,roles r,permissions  p,user_role ur,role_permis rp where u.id=ur.user_id and r.id=ur.role_id and  p.id=rp.permis_id  and
                 r.id=rp.role_id and p.status='1' and  u.loginid=?</value>
         </property>
</bean>

5) userCache &  resourceCache 
  ~存用户和资源相对应的权限信息。每当请求一个受保护资源ӞdaoAuthenticationProvider׃被调用以获取用户授权信息。如果每ơ都从数据库获取的话Q那代h很高Q对于不常改变的用户和资源信息来_最好是把相x权信息缓存v来?详见 
2.6.3 资源权限定义扩展  )
userCache提供了两U实? NullUserCache和EhCacheBasedUserCache, NullUserCache实际上就是不q行M~存QEhCacheBasedUserCache是用Ehcache来实现缓功能?/font>

						<bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
         <property name="cacheManager" ref="cacheManager"/>
         <property name="cacheName" value="userCache"/>
    </bean>
    <bean id="userCache" class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache" autowire="byName">
        <property name="cache" ref="userCacheBackend"/>           </bean>
    <bean id="resourceCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">         <property name="cacheManager" ref="cacheManager"/>                 <property name="cacheName" value="resourceCache"/>
    </bean>
    <bean id="resourceCache" class="org.springside.modules.security.service.acegi.cache.ResourceCache" autowire="byName">
        <property name="cache" ref="resourceCacheBackend"/>
    </bean>


6) basicProcessingFilter 
  用于处理HTTP头的认证信息Q如从Springq程协议(如Hessian和Burlap)或普通的览器如IE,Navigator的HTTP头中获取用户信息Q将他们转交l通过authenticationManager属性装配的认证理器。如果认证成功,会将一个Authentication对象攑ֈ会话中,否则Q如果认证失败,会将控制转交l认证入口点(通过authenticationEntryPoint属性装?

						    <bean id="basicProcessingFilter" class="org.acegisecurity.ui.basicauth.BasicProcessingFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="authenticationEntryPoint" ref="basicProcessingFilterEntryPoint"/>
    </bean>

7) basicProcessingFilterEntryPoint 
  通过向浏览器发送一个HTTP401(未授?消息Q提C用L录?br />处理ZHTTP的授权过E, 在当验证q程出现异常后的"d"Q通常实现转向、在response里加入error信息{功能?/font>

						<bean id="basicProcessingFilterEntryPoint" class="org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint">        
 <property name="realmName" value="SpringSide Realm"/>
</bean>

8) authenticationProcessingFilterEntryPoint 
  当抛出AccessDeniedExceptionӞ用户重定向到登录界面。属性loginFormUrl配置了一个登录表单的URL,当需要用L录时QauthenticationProcessingFilterEntryPoint会将用户重定向到该URL

						 
<bean id="authenticationProcessingFilterEntryPoint" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl">
<value>/security/login.jsp</value>
</property>
<property name="forceHttps" value="false"/>
</bean>

2.2.3 HTTP安全h

1) httpSessionContextIntegrationFilter
  每次request前 HttpSessionContextIntegrationFilter从Session中获取Authentication对象Q在request完后, 又把Authentication对象保存到Session中供下次request使用,此filter必须其他Acegi filter前用,使之能跨多个请求?/font>

						<bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"></bean>
    <bean id="httpRequestAccessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
        <property name="allowIfAllAbstainDecisions" value="false"/>
        <property name="decisionVoters">
            <list>
                <ref bean="roleVoter"/>
            </list>
        </property>
</bean>


2) httpRequestAccessDecisionManager
  l过投票机制来决定是否可以访问某一资源(URL或方?。allowIfAllAbstainDecisions为false时如果有一个或以上的decisionVoters投票通过,则授权通过。可选的决策机制有ConsensusBased和UnanimousBased

						    <bean id="httpRequestAccessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
        <property name="allowIfAllAbstainDecisions" value="false"/>
        <property name="decisionVoters">
            <list>
                <ref bean="roleVoter"/>
            </list>
        </property>
    </bean>


3) roleVoter
   必须是以rolePrefix讑֮的value开头的权限才能q行投票,如AUTH_ , ROLE_

						    <bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter">
        <property name="rolePrefix" value="AUTH_"/>
   </bean>

4Q?strong>exceptionTranslationFilter
  异常转换qo器,主要是处理AccessDeniedException和AuthenticationExceptionQ将l每个异常找到合适的"d" 

						   <bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
        <property name="authenticationEntryPoint" ref="authenticationProcessingFilterEntryPoint"/>
    </bean>

5) authenticationProcessingFilter
  和servlet spec差不?处理登陆h.当n份验证成功时QAuthenticationProcessingFilter会在会话中放|一个Authentication对象Qƈ且重定向到登录成功页?br />         authenticationFailureUrl定义登陆p|时{向的面
         defaultTargetUrl定义登陆成功时{向的面
         filterProcessesUrl定义登陆h的页?br />         rememberMeServices用于在验证成功后dcookie信息

						    <bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="authenticationFailureUrl">
            <value>/security/login.jsp?login_error=1</value>
        </property>
        <property name="defaultTargetUrl">
            <value>/admin/index.jsp</value>
        </property>
        <property name="filterProcessesUrl">
            <value>/j_acegi_security_check</value>
        </property>
        <property name="rememberMeServices" ref="rememberMeServices"/>
    </bean>

6) filterInvocationInterceptor
  在执行{向url前检查objectDefinitionSource中设定的用户权限信息。首先,objectDefinitionSource中定义了讉KURL需要的属性信?q里的属性信息仅仅是标志Q告诉accessDecisionManager要用哪些voter来投?。然后,authenticationManager掉用自己的provider来对用户的认证信息进行校验。最后,有投者根据用h有认证和讉Kurl需要的属性,调用自己的voter来投,军_是否允许讉K?/font>

						    <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
        <property name="objectDefinitionSource" ref="filterDefinitionSource"/>
    </bean>


7) filterDefinitionSource (详见  2.6.3 资源权限定义扩展 )
  自定义DBFilterInvocationDefinitionSource从数据库和cache中读取保护资源及光要的讉K权限信息 

						<bean id="filterDefinitionSource" class="org.springside.modules.security.service.acegi.DBFilterInvocationDefinitionSource">
        <property name="convertUrlToLowercaseBeforeComparison" value="true"/>
        <property name="useAntPath" value="true"/>
        <property name="acegiCacheManager" ref="acegiCacheManager"/>
</bean>

2.2.4 Ҏ调用安全控制

(详见  2.6.3 资源权限定义扩展 )

1) methodSecurityInterceptor
  在执行方法前q行拦截Q检查用h限信?br />2) methodDefinitionSource
  自定义MethodDefinitionSource从cache中读取权?/font>

						   <bean id="methodSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
        <property name="objectDefinitionSource" ref="methodDefinitionSource"/>
    </bean>
    <bean id="methodDefinitionSource" class="org.springside.modules.security.service.acegi.DBMethodDefinitionSource">
        <property name="acegiCacheManager" ref="acegiCacheManager"/>
    </bean>

2.3 Jcaptcha验证?/font>

采用  http://jcaptcha.sourceforge.net  作ؓ通用的验证码ҎQ请参考SpringSide中的例子Q或|上的:
http://www.coachthrasher.com/page/blog?entry=jcaptcha_with_appfuse ?/font>

差沙在此q程中又发现acegi logout filter的错误,q行了修正?/font>



junky 2007-01-30 14:14 发表评论
]]>
Spring的Acegi security的配|,和JDK1.5的一些问??http://www.tkk7.com/junky/archive/2006/12/22/89560.htmljunkyjunkyFri, 22 Dec 2006 08:36:00 GMThttp://www.tkk7.com/junky/archive/2006/12/22/89560.htmlhttp://www.tkk7.com/junky/comments/89560.htmlhttp://www.tkk7.com/junky/archive/2006/12/22/89560.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/89560.htmlhttp://www.tkk7.com/junky/services/trackbacks/89560.html阅读全文

junky 2006-12-22 16:36 发表评论
]]>
Spring AOP with Hibernatehttp://www.tkk7.com/junky/archive/2006/10/17/75602.htmljunkyjunkyTue, 17 Oct 2006 06:08:00 GMThttp://www.tkk7.com/junky/archive/2006/10/17/75602.htmlhttp://www.tkk7.com/junky/comments/75602.htmlhttp://www.tkk7.com/junky/archive/2006/10/17/75602.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/75602.htmlhttp://www.tkk7.com/junky/services/trackbacks/75602.html

One of the sweetiest things the Spring framework gives is Hibernate support is built-in by the time it's born.

Following is a quick guide to configure Hibernate's SessionFactory in Spring. For a detailed version about Spring's Hibernate support, read http://www.springframework.org/docs/data_access.html .



With Spring, Hibernate's SessionFactory no longer needs to bind itself to JNDI; nor use Hibernate's own hibernate.cfg.xml method, which is a little bit tricky to code in Hibernate 2.x (as Hibernate2 doesn't use the once-and-only-once configure() anymore).

Instead, we use org.springframework.orm.hibernate.LocalSessionFactoryBean .

<bean id= "MySessionFactory"  class = "org.springframework.orm.hibernate.LocalSessionFactoryBean" >

    <property name= "mappingResources" >

       <list>

         <value>mappings/Book.hbm.xml</value>

         <value>mappings/Patron.hbm.xml</value>

         <value>mappings/BorrowRecord.hbm.xml</value>

       </list>

    </property>

    <property name= "hibernateProperties" >

       <props>

         <prop key= "hibernate.dialect" >net.sf.hibernate.dialect.MySQLDialect</prop>

         <prop key= "hibernate.query.substitutions" > true = false = 0 </prop>

         <prop key= "hibernate.show_sql" > false </prop>

         <prop key= "hibernate.use_outer_join" > false </prop>

       </props>

    </property>

    <property name= "dataSource" ><ref bean= "MyDataSource" /></property>

</bean>

The above parameters are simple and verbose:

However, we don't need to configure a transaction manager inside the SessionFactory, as we will see below.

After configuring this, we need to provide a setter method in our business objects that need to use Hibernate's SessionFactory:

import  net.sf.hibernate.SessionFactory;

....

public class  MyBusinessObjectImpl  implements  MyBusinessObject

{

    private  SessionFactory sessionFactory;

  

 

public  void  setSessionFactory(SessionFactory sessionFactory)

    {

       this .sessionFactory = sessionFactory;

    }

    public  SessionFactory getSessionFactory()

    {

       return this .sessionFactory;

    }

....

and hook it up to Spring.

<bean id= "MyBusinessObject"  class = "library.MyBusinessObjectImpl" >

    <property name= "sessionFactory" >

       <ref bean= "MySessionFactory" />

    </property>

</bean>

 

How about transactions support? And how do I get Hibernate's Session inside my business objects?

That's Spring framework's another power - HibernateInterceptor and TransactionInterceptor. With them, together with configurations made in Spring, methods inside business objects don't need to write a single line of code for that; instead, a Session will be bound to the business object's current thread, opened and closed automatically; and a transaction will also begin and end automatically.

The sequence is like this:

  1. Transaction begins
  2. Hibernate session opened and bound to the current thread
  3. Actual method execution
  4. Hibernate session bound to the current thread closed
  5. Transaction ended

This is done with the help of Spring's AOP capability.

However, we need to configure a transaction manager first.

<bean id= "MyTransactionManager"  class = "org.springframework.transaction.jta.JtaTransactionManager" />

The above configures a transaction manager that will access an UserTransaction inside the environment, usually in a J2EE container, or a servlet container with transaction support.

Alternately you may want to have a look at org.springframework.orm.hibernate.HibernateTransactionManager .

Next, we need to define the transaction attribute for our business methods. This is done in org.springframework.transaction.interceptor.TransactionInterceptor ? .

<bean id= "MyTransactionInterceptor" 

class = "org.springframework.transaction.interceptor.TransactionInterceptor" >

    <property name= "transactionManager" ><ref bean= "MyTransactionManager" /></property>

    <property name= "transactionAttributeSource" >

   <value>

          library.MyBusinessImpl.borrowBook=PROPAGATION_REQUIRED

          library.MyBusinessImpl.returnBook=PROPAGATION_REQUIRED

          library.BookSearchImpl.*=PROPAGATION_SUPPORTS

   </value>

    </property>

</bean>

You can use a wildcard to tell every method in that business object uses the same transaction attribute. However it is not recommended, as the private methods used inside the business object will have transactions too, which you may not need to.

By the way, the TransactionInterceptor's default behaviour is to commit an transaction anyway, and rollback whenever a RuntimeException is caught - much the same as EJB's behaviour. If you want to control TransactionInterceptor's behaviour when exception is caught, you may tell it with a plus (+) or minus (-) sign, followed by the name of the exception, to commit or rollback a transaction even if an exception mentioned is caught.

An example:

library.MyBusinessImpl.addBook=PROPAGATION_REQUIRED,-SeriesNotFoundException,+CategoryNotFoundException

This means that when SeriesNotFoundException is thrown inside the addBook() method, the transaction will roll back; on the other hand when CategoryNotFoundException is thrown the transaction will be commited anyway.

In most cases you don't need to specify the exception's name with the package it belongs; you just need to specify simply the exception's name.

Then our business objects will need to define as an AOP "target". This is just a change in a name; make sure your code will not call these business objects directly. So change the above business object declaration to

<bean id= "MyBusinessObjectTarget"  class = "library.MyBusinessObjectImpl" >

    <property name= "sessionFactory" >

       <ref bean= "MySessionFactory" />

    </property>

</bean>

Final step is to expose the business object on Spring's ApplicationContext, but not the business object itself; instead we use a ProxyFactoryBean, provided by Spring.

<bean id= "MyBusinessObject"  class = "org.springframework.aop.framework.ProxyFactoryBean" >

    <property name= "proxyInterfaces" >

       <value>library.MyBusinessObject</value>

    </property>

    <property name= "interceptorNames" >

       <list>

          <value>MyTransactionInterceptor</value>

          <value>MyHibernateInterceptor</value>

          <value>MyBusinessObjectTarget</value>

       </list>

    </property>

</bean>

  • proxyInterfaces: the interface implemented by your business object.
  • interceptorNames: the interceptors to be applied when methods on the business interface is called. Be careful, they have to be placed in order.

Then in our business method we just need to obtain the Session instance, and ignore everything else - everything is done behind the scene.

import  net.sf.hibernate.*;

import  org.springframework.orm.hibernate.SessionFactoryUtils;

....

public  Book findBook( int  bookID)  throws  BookNotFoundException, DataAccessException

{

    //get the Session instance already bound to current thread and opened

    Session session = SessionFactoryUtils.getSession(getSessionFactory(),  false );

    try

    {

       Book book = (Book)session.load(Book.class, bookID);

       return  book;

    }

    catch (ObjectNotFoundException e)

    {

       throw new  BookNotFoundException();

    }

    catch (HibernateException e)

    {

       throw  SessionFactoryUtils.convertHibernateAccessException(e);

    }

}

 

Alternately you may also use HibernateTemplate and TransactionTemplate, though the above method is simpler. Read http://www.hibernate.org/110.html for details (this page seems more updated than the one in Spring?).



junky 2006-10-17 14:08 发表评论
]]>
Spring的几个常用的Bean声明http://www.tkk7.com/junky/archive/2006/10/17/75600.htmljunkyjunkyTue, 17 Oct 2006 06:06:00 GMThttp://www.tkk7.com/junky/archive/2006/10/17/75600.htmlhttp://www.tkk7.com/junky/comments/75600.htmlhttp://www.tkk7.com/junky/archive/2006/10/17/75600.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/75600.htmlhttp://www.tkk7.com/junky/services/trackbacks/75600.html 在做 Spring 相关开发时Q时常要用到一些相关的 Bean 的声明,如数据库q接池, hibernate ?/span> SessionFactory 声明{。一下是一些常用到?/span> Bean 声明?/span>



1 Message source 的声明,重要用于pȝ的信息提C?/span>

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">

<property name="basename"><value>messages</value></property>

</bean>

2 属性值的声明Q主要ؓ Bean 声明文g中用:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

<property name="locations">

<list>

<value>WEB-INF/mail.properties</value>

<value>WEB-INF/jdbc.properties</value>

</list>

</property>

</bean>

3 Custom Editor 的注册,以下是日期的注册Q?/span>

<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">

<property name="customEditors">

<map>

<entry key="java.util.Date">

<bean class="org.springframework.beans.propertyeditors.CustomDateEditor">

<constructor-arg index="0">

<bean class="java.text.SimpleDateFormat">

<constructor-arg><value>yyyy-MM-dd</value></constructor-arg>

</bean>

</constructor-arg>

<constructor-arg index="1"><value>false</value></constructor-arg>

</bean>

</entry>

</map>

</property>

</bean>

4 数据库连接池的设|:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

<property name="driverClassName"><value>${jdbc.driverClassName}</value></property>

<property name="url"><value>${jdbc.url}</value></property>

<property name="username"><value>${jdbc.username}</value></property>

<property name="password"><value>${jdbc.password}</value></property>

</bean>

5 hibernate 的设|:

<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">

<property name="dataSource"><ref local="dataSource"/></property>

<property name="mappingResources">

<value>mapping.xml</value>

</property>

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">${hibernate.dialect}</prop>

</props>

</property>

</bean>

6 Jotm 的事务设|:

<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/>

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">

<property name="userTransaction"><ref local="jotm"/></property>

</bean>

7 Hibernate 的事务设|:

<bean id="hibernateTransactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">

<property name="sessionFactory"><ref local="sessionFactory"/></property>

</bean>

8 Bean 的事务声明:

<bean id="clinic" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

<property name="transactionManager"><ref local="hibernateTransactionManager"/></property>

<property name="target"><ref local="clinicTarget"/></property>

<property name="transactionAttributes">

<props>

<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="store*">PROPAGATION_REQUIRED</prop>

</props>

</property>

</bean>

9 Email 的发送者声明:

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">

<property name="host"><value>${mail.host}</value></property>

</bean>

10 基本 Url Mapping 的设|:

<bean id="DemoController" class="cn.edu.bit82.DemoController"/>

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

<property name="mappings">

<props>

<prop key="/hello.html">DemoController</prop>

<prop key="*">SecondController</prop>

</props>

</property>

</bean>

ȝQ?/span> 以上是一些常用的 Bean 的声明,你一般会用到的,你可以?/span> IntelliJ ?/span> Live Template 功能Q可以设|某些参敎ͼ很快完成了 Bean 的声明?/span>



junky 2006-10-17 14:06 发表评论
]]>
ServiceLocator的实?/title><link>http://www.tkk7.com/junky/archive/2006/10/17/75601.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Tue, 17 Oct 2006 06:06:00 GMT</pubDate><guid>http://www.tkk7.com/junky/archive/2006/10/17/75601.html</guid><wfw:comment>http://www.tkk7.com/junky/comments/75601.html</wfw:comment><comments>http://www.tkk7.com/junky/archive/2006/10/17/75601.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/junky/comments/commentRss/75601.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/junky/services/trackbacks/75601.html</trackback:ping><description><![CDATA[ServiceLocator的实?br /><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">/*</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">* Created on 2004-8-25 by simba.</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">*</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">*/</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">package com.simba.blog.util;</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">import javax.servlet.ServletContext;</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">import org.apache.commons.logging.Log;</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">import org.apache.commons.logging.LogFactory;</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">import org.springframework.context.ApplicationContext;</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">import org.springframework.web.context.support.WebApplicationContextUtils;</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">import com.opensymphony.webwork.ServletActionContext;</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">import com.simba.blog.service.BlogService;</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">/**</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">* @author simba</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">* </p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">* email: simbasun@msn.com</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">*/</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">public class ServiceLocator</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">{</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">//the catalog service bean name</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">private static final String BLOG_SERVICE_BEAN_NAME = "blogService";</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">//the user service bean name</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">private static final String USER_SERVICE_BEAN_NAME = "userService";</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">//the logger for this class</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">private Log logger = LogFactory.getLog(this.getClass());</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">//the Spring application context</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">private ApplicationContext appContext;</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">//the cached catalog service</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">private BlogService blogService;</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">//the cached user service</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">//private UserService userService;</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">/**</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">* Constructor.</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">* <p></p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">* The following steps being done:</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">* <ul></p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">* <li>retrieve Spring application context from servlet context.</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">* <li>look up <code>CatalogService</code> from Spring application</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">* context.</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">* <li>look up <code>UserService</code> from Spring applicatino context.</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">* </ul></p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">*/</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">public ServiceLocator()</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">{</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 1in; FONT-FAMILY: tahoma">/*InputStream is = getClass().getResourceAsStream("springapp-servlet.xml"); </p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 1in; FONT-FAMILY: tahoma">XmlBeanFactory bf = new XmlBeanFactory(is); </p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 1in; FONT-FAMILY: tahoma">blogService = (BlogService) bf.getBean("blogService");*/</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 1in; FONT-FAMILY: tahoma"> </p><p style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 1in; FONT-FAMILY: tahoma">ServletContext context = ServletActionContext.getServletContext();</p><p style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 1in; FONT-FAMILY: tahoma">this.appContext = WebApplicationContextUtils.getRequiredWebApplicationContext(context);</p><p style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 1in; FONT-FAMILY: tahoma">this.blogService = (BlogService)this.lookupService(BLOG_SERVICE_BEAN_NAME);</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 1in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 1in; FONT-FAMILY: tahoma">/*</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 1in; FONT-FAMILY: tahoma">* this.userService = (UserService)this.lookupService(USER_SERVICE_BEAN_NAME);</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 1in; FONT-FAMILY: tahoma">*/</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">this.logger.info("Service locator bean is initialized");</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">}</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">/**</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">* Lookup service based on service bean name.</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">* </p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">* @param serviceBeanName the service bean name</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">* @return the service bean</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">*/</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">public Object lookupService(String serviceBeanName)</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">{</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 1in; FONT-FAMILY: tahoma">return appContext.getBean(serviceBeanName);</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">}</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">/**</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">* @return Returns the blogService.</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">*/</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">public BlogService getBlogService()</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">{</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 1in; FONT-FAMILY: tahoma">return blogService;</p><p style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.5in; FONT-FAMILY: tahoma">}</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">}</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">[in web.xml]</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"> </p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"><context-param></p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"><param-name>contextConfigLocation</param-name></p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"><param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value></p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"></context-param></p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"><listener></p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"></listener></p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"><!-- OR USE THE CONTEXTLOADERSERVLET INSTEAD OF THE LISTENER</p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"><servlet></p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"><servlet-name>context</servlet-name></p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"><servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class></p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"><load-on-startup>1</load-on-startup></p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma"></servlet></p><p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: tahoma">--></p><img src ="http://www.tkk7.com/junky/aggbug/75601.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/junky/" target="_blank">junky</a> 2006-10-17 14:06 <a href="http://www.tkk7.com/junky/archive/2006/10/17/75601.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ajax资源 or Ajax Resourceshttp://www.tkk7.com/junky/archive/2006/06/04/50368.htmljunkyjunkySun, 04 Jun 2006 15:23:00 GMThttp://www.tkk7.com/junky/archive/2006/06/04/50368.htmlhttp://www.tkk7.com/junky/comments/50368.htmlhttp://www.tkk7.com/junky/archive/2006/06/04/50368.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/50368.htmlhttp://www.tkk7.com/junky/services/trackbacks/50368.html
资源Q-Q-中文
1 Ajax中国
    http://www.okajax.com/
2 Java 开源大?br />    http://www.open-open.com/

3 安全矩阵QSecurity MatrixQ官方网?br />    http://www.smatrix.org/
4 TechTarget IT专家|-QAjax_IT专家|_Web服务
    http://searchwebservices.techtarget.com.cn/wsdev/ajax/
5 |易学院
    http://tech.163.com/special/c/0009159F/codeother.html
6 Java 视线论坛
    http://forum.javaeye.com/


ResourcesQ-Q-English

1 AJAX开发h员的~译模式:
    http://www.ajaxpatterns.org
2  XMLHttpRequest教程Q“动态网|口?
    http://www.xml.com/pub/a/2005/02/09/xml-http-request.html
3 JavaScript性能基准:
    http://blogs.ebusiness-apps.com/dave/?p=14
4 AJAX资源:
    http://www.ajaxmatters.com
5 JavaScript规范:
    http://www.ecma-international.org/publications/standards/Ecma-262.htm
6 介绍JavaScript对象标识:
    http://www.crockford.com/JSON/index.html
7  Mozilla 的Venkman JavaScript调试?
    http://www.mozilla.org/projects/venkman/
8  XML DOM参?
      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/html/e9da2722-7879-4e48-869c-7f16714e2824.asp
9 Microsoft Dynamic HTML reference:
    http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/dhtml_reference_entry.asp
10 Gecko DOM Reference:
      http://www.mozilla.org/docs/dom/domref/
11 "“移植IE应用到Mozilla?br />    http://www-128.ibm.com/developerworks/web/library/wa-ie2mozgd/
12 Mozilla XUL reference:
    http://www.xulplanet.com/
13 Microsoft XAML reference:
    http://windowssdk.msdn.microsoft.com/library/default.asp?url=/library/en-us/wcp_conceptual/html/0ff5f36e-dd84-44d1-aa3e-            

5bb4f147b169.asp?frame=true
14 James Jesses Garret introduced the term AJAX in his article "AJAX: A New Approach to Web Applications," (Adaptive Path, February 2005):

“AJAXQ新的网应用开发方式?br />    http://www.adaptivepath.com/publications/essays/archives/000385.php
15 JetBrains IntelliJ IDEA:
    http://www.jetbrains.com/
16 Microsoft Visual Studio:
    http://msdn.microsoft.com/vstudio/
17 JSEditor:
    http://jseditor.sourceforge.net/
18 JSEclipse:
    http://www.interaktonline.com/Products/Eclipse/JSEclipse/Overview/
19 ActiveState Komodo:
    http://www.activestate.com/Products/Komodo/
20 XHTML:
    http://www.w3.org/TR/xhtml1/
21 Document Object Model:
    http://www.w3.org/DOM/
22 Cascading Style Sheets:
    http://www.w3.org/Style/CSS/
23 Extensible Stylesheet Language:
    http://www.w3.org/Style/XSL/
24 XForms:
    http://www.w3.org/MarkUp/Forms/
25 Scaling Vector Graphics:
    http://www.w3.org/Graphics/SVG/
26 XPath:
    http://www.w3.org/TR/xpath
27 AJAX.Net:
    http://ajax.schwarz-interactive.de/csharpsample/default.aspx
28 Backbase:
    http://www.backbase.com
29 Bitkraft:
    http://www.tiggrbitz.com/
30 Django:
    http://www.djangoproject.com/
31 Dojo:
    http://www.dojotoolkit.org/
32 DWR (Direct Web Reporting):
    http://getahead.ltd.uk/dwr/
33 MochiKit:
    http://mochikit.com/
34 Prototype:
    http://prototype.conio.net/
35 Rico:
    http://openrico.org/rico/home.page
36 Sajax:
    http://www.modernmethod.com/sajax/
37 Sarissa:
    http://sarissa.sourceforge.net/doc/
38 Script.aculo.us:
    http://script.aculo.us/
39 Ruby on Rails:
    http://www.rubyonrails.org/
40 For more on AJAX and DWR, read "AJAX Made Simple with DWR," Cloves Carneiro Jr. (JavaWorld, June 2005): 关于AJAX和DWRQ请阅读“AJAX使用DWR?br />
单?br />    http://www.javaworld.com/javaworld/jw-06-2005/jw-0620-dwr.html
41 For more articles on Java development tools, browse the Development Tools section of JavaWorld’s Topical Index: 更多Java开发工L文章Q请

览JavaWorld的开发工具部分烦引页
    http://www.javaworld.com/channel_content/jw-tools-index.shtml
42 For more articles on XML, browse the Java and XML section of JavaWorld’s Topical Index: 更多XML的文章,h览JavaWorld的Java和XML部分索引?br />    http://www.javaworld.com/channel_content/jw-xml-index.shtml
43 For more articles on UI design, browse the User Interface Design section of JavaWorld’s Topical Index: 更多UI设计的文章,h览JavaWorld?br />
UI设计部分索引?br />    http://www.javaworld.com/channel_content/jw-ui-index.shtml


junky 2006-06-04 23:23 发表评论
]]>
Spring in Action W记V -- 使用Spring来发邮g和执行定时Q?http://www.tkk7.com/junky/archive/2006/05/31/49357.htmljunkyjunkyWed, 31 May 2006 15:04:00 GMThttp://www.tkk7.com/junky/archive/2006/05/31/49357.htmlhttp://www.tkk7.com/junky/comments/49357.htmlhttp://www.tkk7.com/junky/archive/2006/05/31/49357.html#Feedback2http://www.tkk7.com/junky/comments/commentRss/49357.htmlhttp://www.tkk7.com/junky/services/trackbacks/49357.html阅读全文

junky 2006-05-31 23:04 发表评论
]]>
Spring in Action W记(III) -- 在Spring下的Hibernate操作数据?/title><link>http://www.tkk7.com/junky/archive/2006/05/29/48849.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Mon, 29 May 2006 15:20:00 GMT</pubDate><guid>http://www.tkk7.com/junky/archive/2006/05/29/48849.html</guid><wfw:comment>http://www.tkk7.com/junky/comments/48849.html</wfw:comment><comments>http://www.tkk7.com/junky/archive/2006/05/29/48849.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/junky/comments/commentRss/48849.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/junky/services/trackbacks/48849.html</trackback:ping><description><![CDATA[ <p align="center"> <strong>Spring in Action W记(III)</strong> </p> <p>By: icess blog: <a ><font color="#002c99">http://blog.matrix.org.cn/page/icess</font></a></p> <p>q次来看看用Spring的Hibernate模板来操作数? Spring提供了Hibernate的一层包?使Hibernate使用h更加方便,其是结合Hibernate Annotation? 配置文g更少,l护更加? 下面来看看吧.</p> <p>下面是一个测试数据实体类<font color="#000000"><code style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New', Courier">TestData.java 和前一提到的实体cM?只不q用了Annotation注释. </code></font></p> <p> <code style="FONT-SIZE: 10pt; MARGIN: 0px; FONT-FAMILY: 'Courier New', Courier"> <font color="#7f0055"> <b>package </b> </font> <font color="#000000">test.orm.hibernate.model;</font> <br /> <br /> <font color="#7f0055"> <b>import </b> </font> <font color="#000000">javax.persistence.Basic;</font> <br /> <font color="#7f0055"> <b>import </b> </font> <font color="#000000">javax.persistence.Entity;</font> <br /> <font color="#7f0055"> <b>import </b> </font> <font color="#000000">javax.persistence.Id;</font> <br /> <font color="#7f0055"> <b>import </b> </font> <font color="#000000">javax.persistence.Table;</font> <br /> <br /> <br /> <font color="#000000">@Entity</font> <br /> <font color="#000000">@Table(name = </font> <font color="#2a00ff">"test"</font> <font color="#000000">,schema = </font> <font color="#2a00ff">"APP"</font> <font color="#000000">)</font> <br /> <font color="#7f0055"> <b>public class </b> </font> <font color="#000000">TestData {</font> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>private int </b> </font> <font color="#000000">id;</font> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>private </b> </font> <font color="#000000">String name;</font> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>public </b> </font> <font color="#000000">TestData(</font> <font color="#7f0055"> <b>int </b> </font> <font color="#000000">id, String name) {</font> <br /> <font color="#ffffff">    </font> <font color="#7f0055"> <b>this</b> </font> <font color="#000000">.id = id;</font> <br /> <font color="#ffffff">    </font> <font color="#7f0055"> <b>this</b> </font> <font color="#000000">.name = name;</font> <br /> <font color="#ffffff">  </font> <font color="#000000">}</font> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>public </b> </font> <font color="#000000">TestData() {}</font> <br /> <font color="#ffffff">  </font> <br /> <font color="#ffffff">  </font> <font color="#000000">@Id</font> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>public int </b> </font> <font color="#000000">getId() {</font> <br /> <font color="#ffffff">    </font> <font color="#7f0055"> <b>return </b> </font> <font color="#000000">id;</font> <br /> <font color="#ffffff">  </font> <font color="#000000">}</font> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>public void </b> </font> <font color="#000000">setId(</font> <font color="#7f0055"> <b>int </b> </font> <font color="#000000">id) {</font> <br /> <font color="#ffffff">    </font> <font color="#7f0055"> <b>this</b> </font> <font color="#000000">.id = id;</font> <br /> <font color="#ffffff">  </font> <font color="#000000">}</font> <br /> <font color="#ffffff">  </font> <font color="#000000">@Basic</font> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>public </b> </font> <font color="#000000">String getName() {</font> <br /> <font color="#ffffff">    </font> <font color="#7f0055"> <b>return </b> </font> <font color="#000000">name;</font> <br /> <font color="#ffffff">  </font> <font color="#000000">}</font> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>public void </b> </font> <font color="#000000">setName(String name) {</font> <br /> <font color="#ffffff">    </font> <font color="#7f0055"> <b>this</b> </font> <font color="#000000">.name = name;</font> <br /> <font color="#ffffff">  </font> <font color="#000000">}</font> <br /> <font color="#000000">}</font> </code> </p> <p>下面是测试Hibernate模板的类, <font color="#000000"><code style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New', Courier">TestHibernateTemplate.java</code></font></p> <p> <code style="FONT-SIZE: 10pt; MARGIN: 0px; FONT-FAMILY: 'Courier New', Courier"> <font color="#7f0055"> <b>package </b> </font> <font color="#000000">test.orm.hibernate;</font> <br /> <br /> <font color="#7f0055"> <b>import </b> </font> <font color="#000000">java.sql.SQLException;</font> <br /> <br /> <font color="#7f0055"> <b>import </b> </font> <font color="#000000">org.hibernate.HibernateException;</font> <br /> <font color="#7f0055"> <b>import </b> </font> <font color="#000000">org.hibernate.Session;</font> <br /> <font color="#7f0055"> <b>import </b> </font> <font color="#000000">org.springframework.orm.hibernate3.HibernateCallback;</font> <br /> <font color="#7f0055"> <b>import </b> </font> <font color="#000000">org.springframework.orm.hibernate3.HibernateTemplate;</font> <br /> <br /> <font color="#7f0055"> <b>import </b> </font> <font color="#000000">test.orm.hibernate.model.TestData;</font> <br /> <br /> <br /> <font color="#7f0055"> <b>public class </b> </font> <font color="#000000">TestHibernateTemplate {</font> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>private </b> </font> <font color="#000000">HibernateTemplate hibernateTemplate;</font> <br /> <font color="#ffffff">  </font> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>public </b> </font> <font color="#000000">TestHibernateTemplate() {}</font> <br /> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>public </b> </font> <font color="#000000">HibernateTemplate getHibernateTemplate() {</font> <br /> <font color="#ffffff">    </font> <font color="#7f0055"> <b>return </b> </font> <font color="#000000">hibernateTemplate;</font> <br /> <font color="#ffffff">  </font> <font color="#000000">}</font> <br /> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>public void </b> </font> <font color="#000000">setHibernateTemplate(HibernateTemplate hibernateTemplate) {</font> <br /> <font color="#ffffff">    </font> <font color="#7f0055"> <b>this</b> </font> <font color="#000000">.hibernateTemplate = hibernateTemplate;</font> <br /> <font color="#ffffff">  </font> <font color="#000000">}</font> <br /> <font color="#ffffff">  </font> <br /> <font color="#ffffff">  </font> <font color="#3f7f5f">//试使用HibernateTemplate来操作数?/font> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>public </b> </font> <font color="#000000">TestData getTestData(</font> <font color="#7f0055"> <b>final int </b> </font> <font color="#000000">id) {</font> <br /> <font color="#ffffff">    </font> <font color="#7f0055"> <b>return </b> </font> <font color="#000000">(TestData) hibernateTemplate.execute(</font> <font color="#7f0055"> <b>new </b> </font> <font color="#000000">HibernateCallback() {</font> <br /> <br /> <font color="#ffffff">      </font> <font color="#7f0055"> <b>public </b> </font> <font color="#000000">Object doInHibernate(Session s) </font> <font color="#7f0055"> <b>throws </b> </font> <font color="#000000">HibernateException, SQLException {</font> <br /> <font color="#ffffff">        </font> <font color="#3f7f5f">// TODO Auto-generated method stub</font> <br /> <font color="#ffffff">        </font> <font color="#7f0055"> <b>return </b> </font> <font color="#000000">s.get(TestData.class, id);</font> <br /> <font color="#ffffff">      </font> <font color="#000000">}</font> <br /> <font color="#ffffff">      </font> <br /> <font color="#ffffff">    </font> <font color="#000000">});</font> <br /> <font color="#ffffff">  </font> <font color="#000000">}</font> <br /> <font color="#3f7f5f">//  上面查询数据的方法 用了HibernateCallBack接口,对于q样单的查询,可以使用下面由HibernateTemplate 提供的更单的Ҏ</font> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>public </b> </font> <font color="#000000">TestData getTestData2(</font> <font color="#7f0055"> <b>final int </b> </font> <font color="#000000">id) {</font> <br /> <font color="#ffffff">    </font> <font color="#7f0055"> <b>return </b> </font> <font color="#000000">(TestData) hibernateTemplate.get(TestData.class, id);</font> <br /> <font color="#ffffff">  </font> <font color="#000000">}</font> <br /> <font color="#ffffff">  </font> <font color="#3f7f5f">/* 如果上面的两处方法用Load Ҏ的时, 抛出延迟加蝲属性异? Spring理Session的问? 应该是Spring用完Session 然后关闭了,</font> <br /> <font color="#ffffff">   </font> <font color="#3f7f5f">* 所以不可以延迟加蝲, 也就不可以用load Ҏ?,????? Z????*/</font> <br /> <font color="#ffffff">  </font> <br /> <font color="#ffffff">  </font> <font color="#3f7f5f">// 其他操作数据Ҏ ? 插入,修改.... 和用Hibernate session 差不? HibernateTemplate只是Session的包?/font> <br /> <font color="#000000">}</font> </code> </p> <p>可以看到使用Hibernate模板来操作数?是多么简? </p> <p>注意: 上面注释?提到了在使用LoadҎ时?会有问题, Session in view 时候用load是不会出问题? q里Spring提供的方法应该是按照Hibernate的语义写的吧.</p> <p>下面是用来试上面的类是否正常工作的测试类?<font color="#000000"><code style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New', Courier">TestApp.java</code></font></p> <p> <code style="FONT-SIZE: 10pt; MARGIN: 0px; FONT-FAMILY: 'Courier New', Courier"> <font color="#7f0055"> <b>package </b> </font> <font color="#000000">test.orm.hibernate;</font> <br /> <br /> <font color="#7f0055"> <b>import </b> </font> <font color="#000000">org.springframework.context.ApplicationContext;</font> <br /> <font color="#7f0055"> <b>import </b> </font> <font color="#000000">org.springframework.context.support.ClassPathXmlApplicationContext;</font> <br /> <br /> <font color="#7f0055"> <b>import </b> </font> <font color="#000000">test.jdbc.DatabaseUtils;</font> <br /> <font color="#7f0055"> <b>import </b> </font> <font color="#000000">test.orm.hibernate.model.TestData;</font> <br /> <br /> <font color="#7f0055"> <b>public class </b> </font> <font color="#000000">TestApp {</font> <br /> <br /> <font color="#ffffff">  </font> <font color="#3f5fbf">/**</font> <br /> <font color="#ffffff">   </font> <font color="#3f5fbf">* </font> <font color="#7f9fbf">@param </font> <font color="#3f5fbf">args</font> <br /> <font color="#ffffff">   </font> <font color="#3f5fbf">*/</font> <br /> <font color="#ffffff">  </font> <font color="#7f0055"> <b>public static void </b> </font> <font color="#000000">main(String[] args) {</font> <br /> <font color="#ffffff">    </font> <font color="#3f7f5f">// TODO Auto-generated method stub</font> <br /> <font color="#ffffff">    </font> <font color="#000000">DatabaseUtils dataUtils = </font> <font color="#7f0055"> <b>new </b> </font> <font color="#000000">DatabaseUtils();</font> <br /> <font color="#ffffff">    </font> <font color="#000000">dataUtils.connect();</font> <br /> <font color="#ffffff">    </font> <font color="#000000">System.out.println(</font> <font color="#2a00ff">"Open database:!"</font> <font color="#000000">);</font> <br /> <font color="#ffffff">    </font> <font color="#000000">ApplicationContext context = </font> <font color="#7f0055"> <b>new </b> </font> <font color="#000000">ClassPathXmlApplicationContext(</font> <font color="#2a00ff">"test/orm/hibernate/spring-hibernate.xml"</font> <font color="#000000">);</font> <br /> <font color="#ffffff">    </font> <br /> <font color="#ffffff">    </font> <font color="#000000">TestHibernateTemplate hibernateTemplate = (TestHibernateTemplate) context.getBean(</font> <font color="#2a00ff">"testDao"</font> <font color="#000000">);</font> <br /> <font color="#ffffff">    </font> <br /> <font color="#ffffff">    </font> <font color="#000000">System.out.println(</font> <font color="#2a00ff">"name : " </font> <font color="#000000">);</font> <br /> <font color="#ffffff">    </font> <font color="#000000">TestData data = hibernateTemplate.getTestData(</font> <font color="#990000">9</font> <font color="#000000">);</font> <br /> <font color="#ffffff">    </font> <font color="#000000">System.out.println(</font> <font color="#2a00ff">"name : " </font> <font color="#000000">+ data.getName());</font> <br /> <font color="#ffffff">    </font> <font color="#000000">data = hibernateTemplate.getTestData2(</font> <font color="#990000">3</font> <font color="#000000">);</font> <br /> <font color="#ffffff">    </font> <font color="#000000">System.out.println(</font> <font color="#2a00ff">"name 2: " </font> <font color="#000000">+ data.getName());</font> <br /> <font color="#ffffff">    </font> <br /> <font color="#ffffff">    </font> <br /> <font color="#ffffff">    </font> <font color="#000000">dataUtils.disconnect();</font> <br /> <font color="#ffffff">    </font> <br /> <font color="#ffffff">  </font> <font color="#000000">}</font> <br /> <br /> <font color="#000000">}</font> </code> </p> <p> </p> <p>注意: 本测试中用到了上一用到?font color="#000000"><code style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New', Courier">DatabaseUtils.java 工具cL操作Derby数据?</code></font></p> <p> <code> <font size="2"> <span style="FONT-FAMILY: 'Courier New', Courier">?/span> </font> </code> <font color="#000000"> <code style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New', Courier">以上实例可以看出,在Spring中用Hibernate,效率更高一? 你不q样认ؓ?</code> </font> </p> <p> <code> <font size="2"> <span style="FONT-FAMILY: 'Courier New', Courier">同时</span> </font> </code> <font color="#000000"> <code style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New', Courier">Spring也提供了 JDO{其他一些数据操作框架的包装,使用上基本上 是一Lq里׃在详qC.</code> </font> </p> <p> <code> <font size="2"> <span style="FONT-FAMILY: 'Courier New', Courier">下一ơ我们来看看Spring的I18N处理,和自定义属性编辑器的实?</span> </font> </code> </p> <img src ="http://www.tkk7.com/junky/aggbug/48849.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/junky/" target="_blank">junky</a> 2006-05-29 23:20 <a href="http://www.tkk7.com/junky/archive/2006/05/29/48849.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring in Action W记 (IV) -- i18n问题和自定义属性编辑器http://www.tkk7.com/junky/archive/2006/05/29/48846.htmljunkyjunkyMon, 29 May 2006 15:19:00 GMThttp://www.tkk7.com/junky/archive/2006/05/29/48846.htmlhttp://www.tkk7.com/junky/comments/48846.htmlhttp://www.tkk7.com/junky/archive/2006/05/29/48846.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/48846.htmlhttp://www.tkk7.com/junky/services/trackbacks/48846.htmlSpring in Action W记 (IV) -- i18n问题和自定义属性编辑器

  BY: icess Blog: http://blog.matrix.org.cn/page/icess 

   在Spring中处理I18N问题和用Java里面的类基本上是一L.使用org.springframework.context.support.ResourceBundleMessageSource

然后注入资源文g(一个名字ؓbasename的属?,然后可以在Context中用资源文件了, 如下Z个配|示? test.xml

<?

xml version = "1.0" encoding = "UTF-8" ?>

<!

DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "spring-beans.dtd" >

<

beans >

< bean id = "messageSource" class = "org.springframework.context.support.ResourceBundleMessageSource" >

< property name = "basename" >

<!-- 注意此处讄 资源 名字 和\?-->

< value > test/i18n/test </ value >

</ property >

</ bean >

</

beans >

下面源文?test.properties

name =

\u51B0\u96E8

sex =

\u5148\u751F

test_zh.properties

name =

\u51B0\u96E8

sex =

\u5148\u751F

test_en_US.properties

name =

ice rain

sex =

male

下面是一个简单的试c?

package

test.i18n;

import

java.util.Locale;

import

org.springframework.context.ApplicationContext;

import

org.springframework.context.support.ClassPathXmlApplicationContext;

public

class TestI18n {

/**

* @param args

*/

  public static void main(String[] args) {

    // TODO Auto-generated method stub

    ApplicationContext context =

new ClassPathXmlApplicationContext( "test/i18n/test.xml" );

    String text = context.getMessage(

"sex" , new Object[0], Locale. US );

    String textZH = context.getMessage(

"sex" , new Object[0], Locale. CHINA );

    System.

out .println(text + " 中文:" +textZH);

  }

}

很简?q样可以了.

下面来看看Spring中的属性自定义~辑?q个和Hibernate中的自定义属性差不多 ? 例如下面我们要看C例子,映射一个电话号??font size="2">areaCode,prefix?number, 如果不用自定义属性编辑器那么p分别注入上面?个代?ȝ. 如果使用自定义属性编辑器,直接注入一?分开的数字序列就可以??/p>

888-666-9999

.在下面的例子中的Contact.javacL个PhoneNumber属?里面保存了上面的3个代?两个cȝ代码如下:

package  test.propertyEditor;

public class  Contact {
   private  PhoneNumber phoneNumber;
   private  String name;
  
   public  Contact() {}
  
   public  String getName() {
     return  name;
   }

   public void  setName(String name) {
     this .name = name;
   }

   public  PhoneNumber getPhoneNumber() {
     return  phoneNumber;
   }

   public void  setPhoneNumber(PhoneNumber phoneNumber) {
     this .phoneNumber = phoneNumber;
   }
  
}

PhoneNumber.java

package  test.propertyEditor;

public class  PhoneNumber {
   private  String areaCode;
   private  String prefix;
   private  String number;
   public  PhoneNumber() {
    
   }
   public  PhoneNumber(String areaCode,String prefix,String number) {
     this .areaCode = areaCode;
     this .prefix = prefix;
     this .number = number;
   }
   public  String getAreaCode() {
     return  areaCode;
   }
   public void  setAreaCode(String areaCode) {
     this .areaCode = areaCode;
   }
   public  String getNumber() {
     return  number;
   }
   public void  setNumber(String number) {
     this .number = number;
   }
   public  String getPrefix() {
     return  prefix;
   }
   public void  setPrefix(String prefix) {
     this .prefix = prefix;
   }
}

然后定义一个用来编辑PhoneNumber的编辑器PhoneEditor.java 如下:

package  test.propertyEditor;

import  java.beans.PropertyEditorSupport;

public class  PhoneEditor  extends  PropertyEditorSupport {
   public void  setAsText(String textValue) {
     String stripped = stripNonNumber(textValue);
    
     String areaCode = stripped.substring( 0 , 3 );
     String prefix = stripped.substring( 3 , 6 );
     String number = stripped.substring( 6 );
     PhoneNumber phone =  new  PhoneNumber(areaCode,prefix,number);
    
     setValue(phone);
   }
  
   private  String stripNonNumber(String original) {
     StringBuilder allNumeric =  new  StringBuilder();
    
     for ( int  i =  0 ; i < original.length(); i ++) {
       char  c = original.charAt(i);
       if (Character.isDigit(c)) {
         allNumeric.append(c);
       }
     }
     return  allNumeric.toString();
   }
}

l承java里面的属性编辑器,实现里面的一个方法就可以? 下面是在配|文件中注册该编辑器.如下:

testPropertyEditor.xml

<?

xml version = "1.0" encoding = "UTF-8" ?>

<!

DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "spring-beans.dtd" >

<

beans >

< bean id = "customEditorConfigurer" class = "org.springframework.beans.factory.config.CustomEditorConfigurer" >

< property name = "customEditors" >

< map >

< entry key = "test.propertyEditor.PhoneNumber" >

< bean id = "phoneEditor" class = "test.propertyEditor.PhoneEditor" ></ bean >

</ entry >

</ map >

</ property >

</ bean >

<!-- 如果不注册上面自定义Editor的实? 需要注册一个PhoneNumber的bean,讄其属性然后再注册

Contact的PhoneNumber的属?/p>

-->

< bean id = "contact" class = "test.propertyEditor.Contact" >

< property name = "phoneNumber" >

< value > 888-666-9999 </ value >

</ property >

</ bean >

</

beans >

最后来试一下注册的l果是否正确:

package  test.propertyEditor;

import  org.springframework.context.ApplicationContext;
import  org.springframework.context.support.ClassPathXmlApplicationContext;

public class  TestPropertyEditor {

   /**
    @param  args
    */
   public static void  main(String[] args) {
     // TODO Auto-generated method stub
     ApplicationContext context =  new  ClassPathXmlApplicationContext( "test/propertyEditor/testPropertyEditor.xml" );
     Contact c = (Contact) context.getBean( "contact" );
    
     System.out.println(c.getPhoneNumber().getAreaCode());
     System.out.println(c.getPhoneNumber().getPrefix());
     System.out.println(c.getPhoneNumber().getNumber());
   }

}

ok, 很简?下一ơ来看看,Spring提供的一下比较有意思的功能.如定?发送Email{?



junky 2006-05-29 23:19 发表评论
]]>
Spring in Action W记(II) part II http://www.tkk7.com/junky/archive/2006/05/25/48175.htmljunkyjunkyThu, 25 May 2006 12:22:00 GMThttp://www.tkk7.com/junky/archive/2006/05/25/48175.htmlhttp://www.tkk7.com/junky/comments/48175.htmlhttp://www.tkk7.com/junky/archive/2006/05/25/48175.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/48175.htmlhttp://www.tkk7.com/junky/services/trackbacks/48175.html阅读全文

junky 2006-05-25 20:22 发表评论
]]>
Spring in Action W记(II) part I http://www.tkk7.com/junky/archive/2006/05/25/48174.htmljunkyjunkyThu, 25 May 2006 12:21:00 GMThttp://www.tkk7.com/junky/archive/2006/05/25/48174.htmlhttp://www.tkk7.com/junky/comments/48174.htmlhttp://www.tkk7.com/junky/archive/2006/05/25/48174.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/48174.htmlhttp://www.tkk7.com/junky/services/trackbacks/48174.html Spring in Action W记 (II)

今天来看看用JDBC来操作数据: 使用的是DerbyQJavaDBQ数据库Q关于JavaDB的介l请点击q里Q?/font> http://blog.matrix.org.cn/page/icess?catname=%2FJavaDB ?下面建立一个DatabaseUtils.java的工LQ来操作数据?。该cd上面的连接的文章中有讲述?/font>

package  test.jdbc;

import  java.io.File;
import  java.io.IOException;
import  java.io.InputStream;
import  java.sql.Connection;
import  java.sql.DriverManager;
import  java.sql.PreparedStatement;
import  java.sql.ResultSet;
import  java.sql.SQLException;
import  java.sql.Statement;
import  java.util.Properties;
import  java.util.logging.Logger;

public class  DatabaseUtils {
   private static final  String DB_PROPERTIES_FILE =  "jdbc.properties" ;

   private static final  String DB_OPPOSITE_LOCATION =  "/.test" ;

   static  Logger logger = Logger.getLogger(DatabaseUtils. class .getName());

   private  Connection dbConnection;

   private  Properties dbProperties;

   private boolean  isConnected;

   // database name
   private  String dbName;

   private static final  String strCreateTestClobTeble =  "CREATE TABLE APP.test (id INT, name VARCHAR(30),text CLOB(64 K))" ;

   private static final  String strInsertIntoTestTeble =  "INSERT INTO APP.test (id, name)  VALUES (?, ?)" ;
   public static final  String strGetTest =  "SELECT * FROM APP.test WHERE ID = ?" ;
   private static final  String strCreateCourseTable =  "create table APP.Course ("
       "    ID          INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),"
       "    name    VARCHAR(30), "
       "    description  VARCHAR(30), "
       "    startDate  DATE, "  "    endDate     DATE "  ")" ;

   private static final  String strCreateStudentTable =  "create table APP.ADDRESS ("
       "    ID          INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),"
       "    LASTNAME    VARCHAR(30), "
       "    FIRSTNAME   VARCHAR(30), "
       "    MIDDLENAME  VARCHAR(30), "
       "    PHONE       VARCHAR(20), "
       "    EMAIL       VARCHAR(30), "
       "    ADDRESS1    VARCHAR(30), "
       "    ADDRESS2    VARCHAR(30), "
       "    CITY        VARCHAR(30), "
       "    STATE       VARCHAR(30), "  ")" ;

   public  DatabaseUtils() {
     this ( "test" );
   }

   public  DatabaseUtils(String dbName) {
     this .dbName = dbName;

     setDBSystemDir();
     dbProperties = loadDBProperties();
     String driverName = dbProperties.getProperty( "db.driver" );
     loadDatabaseDriver(driverName);
     if  (!dbExists()) {
       createDatabase();
     }
   }

   private  Properties loadDBProperties() {
     InputStream dbPropInputStream =  null ;

     dbPropInputStream = DatabaseUtils. class
         .getResourceAsStream(DB_PROPERTIES_FILE);
     dbProperties =  new  Properties();

     try  {
       dbProperties.load(dbPropInputStream);
     catch  (IOException e) {
       e.printStackTrace();
     }
     return  dbProperties;
   }

   private void  setDBSystemDir() {
     String userDir = System.getProperty( "user.dir" "." );
     String systemDir = userDir + DB_OPPOSITE_LOCATION;
     System.setProperty( "derby.system.home" , systemDir);

     // create the db System dir
     File fileSystemDir =  new  File(systemDir);
     fileSystemDir.mkdir();
   }

   private void  loadDatabaseDriver(String driverName) {
     try  {
       Class.forName(driverName);
     catch  (ClassNotFoundException e) {
       e.printStackTrace();
     }
   }

   private boolean  dbExists() {
     boolean  bExists =  false ;
     String dbLocation = getDatabaseLocation();
     File dbFileDir =  new  File(dbLocation);
     if  (dbFileDir.exists()) {
       bExists =  true ;
     }
     return  bExists;
   }

   private boolean  createDatabase() {
     boolean  bCreated =  false ;
     Connection dbConnection =  null ;

     String dbUrl = getDatabaseUrl();
     dbProperties.put( "create" "true" );

     try  {
       dbConnection = DriverManager.getConnection(dbUrl, dbProperties);
       bCreated = createTables(dbConnection, strCreateTestClobTeble);
     catch  (SQLException e) {
       e.printStackTrace();
     }

     dbProperties.remove( "create" );
     return  bCreated;
   }

   private boolean  createTables(Connection dbConnection, String creatTableSql) {
     boolean  bCreatedTables =  false ;
     Statement statement =  null ;

     try  {
       statement = dbConnection.createStatement();
       statement.execute(creatTableSql);
       bCreatedTables =  true ;
     catch  (SQLException e) {
       e.printStackTrace();
     }
     return  bCreatedTables;
   }

   public  String getDatabaseUrl() {

     return  dbProperties.getProperty( "db.url" ) + dbName;
   }

   public  String getDatabaseLocation() {
     String dbLocation = System.getProperty( "derby.system.home" ) +  "/"
         + dbName;
     return  dbLocation;
   }

   public boolean  connect() {
     String dbUrl = getDatabaseUrl();
     try  {
       logger.info( "DBUrl: "  + dbUrl);
       dbConnection = DriverManager.getConnection(dbUrl, dbProperties);
       isConnected = dbConnection !=  null ;
     catch  (SQLException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
       isConnected =  false ;
       logger.info( "create connection if failed!" );
     }
     return  isConnected;
   }

   public  Connection getConnection() {
     return  dbConnection;
   }

   public void  disconnect() {
     if  (isConnected) {
       String dbUrl = getDatabaseUrl();
       dbProperties.put( "shutdown" "true" );
       try  {
         System.out.println( "断开数据库连????????????????" );
         DriverManager.getConnection(dbUrl, dbProperties);
         System.out.println( "????????????????" );
       catch  (SQLException e) {
         // e.printStackTrace();
         logger.info( "disconnect the connection Successful!" );
       }
       isConnected =  false ;
     }
   }

   /**
    @param  args
    */
   public static void  main(String[] args) {
     // TODO Auto-generated method stub
     DatabaseUtils testdb =  new  DatabaseUtils();
     logger.info(testdb.getDatabaseLocation());
     logger.info(testdb.getDatabaseUrl());
     testdb.connect();
     Connection c = testdb.getConnection();
     PreparedStatement ps =  null ;
     try  {
       ps = c.prepareStatement(DatabaseUtils.strInsertIntoTestTeble, Statement.RETURN_GENERATED_KEYS);
       ps.setInt( 1 1 );
       ps.setString( 2 "test Icerain" );
       int  i =ps.executeUpdate();
       System.out.println(i);
       ps.close();
      
       ps = c.prepareStatement(DatabaseUtils.strGetTest);
       ps.setInt( 1 1 );
       ResultSet rs = ps.executeQuery();
       if (rs.next()) {
         String name = rs.getString( 2 );
         System.out.println(name);
       }
       ps.close();
     catch  (SQLException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
     }
     testdb.disconnect();
   }

}

 

下面是一个插入数据的c?InsertData.java

package  test.jdbc;

import  java.sql.Types;

import  javax.sql.DataSource;

import  org.springframework.jdbc.core.SqlParameter;
import  org.springframework.jdbc.object.SqlUpdate;

public class  InsertData  extends  SqlUpdate {
   // 需要注入一个DataSource...
   public  InsertData(DataSource ds) {
     setDataSource(ds);   // TODO 注意 讄数据?/font>
     setSql( "INSERT INTO APP.test (id, name)  VALUES (?, ?)" );
     declareParameter( new  SqlParameter(Types.INTEGER));
     declareParameter( new  SqlParameter(Types.VARCHAR));
    
     compile(); // TODO 注意 , 要编译以后才可以使用
   }
  
   // 覆盖insertҎ
   public int  insert(TestData data) {
     Object[] params =  new  Object[] {data.id,data.name};
     return  update(params);   // 执行插入操作....
   }

}

很简? q带有详l注?

下面是一个查询的c?QueryDataById.java

package  test.jdbc;

import  java.sql.ResultSet;
import  java.sql.SQLException;
import  java.sql.Types;

import  javax.sql.DataSource;

import  org.springframework.jdbc.core.SqlParameter;
import  org.springframework.jdbc.object.MappingSqlQuery;

public class  QueryDataById  extends  MappingSqlQuery{
   private static final  String sql =  "SELECT * FROM APP.test WHERE ID = ?" ;
   public  QueryDataById(DataSource ds) {
     super (ds,sql);
     declareParameter( new  SqlParameter( "id" ,Types.INTEGER));
     compile();
   }
 

  // 覆盖mapRowҎ
   @Override
   protected  Object mapRow(ResultSet rs,  int  index)  throws  SQLException {
     // TODO Auto-generated method stub
     TestData tdata =  new  TestData();
     tdata.id = rs.getInt( 1 );
     tdata.name = rs.getString( 2 );
    
     return  tdata;
   }
  
}

 

也很?

注意:

 以上两个c都实现了Spring化Jdbc操作的一些接? 关于接口的信息请查考文? q里不在详细讲述.

 

下面是一个很单的试(数据)实体c?TestData.java

package  test.jdbc;

public class  TestData {
   public int  id;
   public  String name;
   public  TestData( int  id, String name) {
     this .id = id;
     this .name = name;
   }
   public  TestData() {}
}

下面是一个测试数据源是否注入正确的类:TestDataSource.java

package  test.jdbc;

import  java.sql.Connection;
import  java.sql.PreparedStatement;
import  java.sql.ResultSet;

import  javax.sql.DataSource;

public class  TestDataSource {
   private  DataSource dataSource;
 

// 注入数据?/span>
   public void  setDataSource(DataSource dataSource) {
     this .dataSource = dataSource;
   }
 

//试数据?/span>
   public void  testDataSource() {
     try  {
       System.out.println( "Test DataSource!!!" );
       Connection connection = dataSource.getConnection();
       if  (connection !=  null )
         System.out.println( "test ok!" );
      
       PreparedStatement ps =  null ;
       ps = connection.prepareStatement(DatabaseUtils.strGetTest);
       ps.setInt( 1 1 );
       ResultSet rs = ps.executeQuery();
       if (rs.next()) {
         String name = rs.getString( 2 );
         System.out.println( "试数据源配|?"  + name);
       }
       ps.close();
     catch  (Exception e) {
       e.printStackTrace();
     }
   }

}

下面是测试Spring提高的Jdbc功能的主要测试类, 试了一些用JDBC操作数据的常用功? 其他没有试的请查看其Doc,TestJdbcTemplate.java



junky 2006-05-25 20:21 发表评论
]]>
Spring in Action W记(I) http://www.tkk7.com/junky/archive/2006/05/23/47703.htmljunkyjunkyTue, 23 May 2006 11:37:00 GMThttp://www.tkk7.com/junky/archive/2006/05/23/47703.htmlhttp://www.tkk7.com/junky/comments/47703.htmlhttp://www.tkk7.com/junky/archive/2006/05/23/47703.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/47703.htmlhttp://www.tkk7.com/junky/services/trackbacks/47703.html在考试前匆匆看了一遍Spring in Action 也没有记录什?考试l束?要抓紧时间整理一?要不然就忘了.^_^:

整理一下我目前可能会用到的模块, 对于那些现在Ҏ用不到的冬冬q是{有旉再研I吧!

W一个当然是最l典的HelloWorld ?, 呵呵,?但是说明了原?

定义一个服务接?/p>

package  test.helloworld;

public interface  GreetingService {
   public void  sayGreeting();

}

下面是其实现:

package  test.helloworld;

public class  GreetingServiceImpl  implements  GreetingService {

   private  String greeting;
   public  GreetingServiceImpl() {}
   public  GreetingServiceImpl(String greeting) {
     this .greeting = greeting;
   }
   public void  sayGreeting() {
     //  Auto-generated method stub
     System.out.println(greeting);
   }
  
   public void  setGreeting(String greeting) {
     this .greeting = greeting;
   }

}

然后是试 IoC 的测试代?

package  test.helloworld;


import  org.springframework.beans.factory.BeanFactory;
import  org.springframework.beans.factory.xml.XmlBeanFactory;
import  org.springframework.context.ApplicationContext;
import  org.springframework.context.support.ClassPathXmlApplicationContext;
import  org.springframework.core.io.FileSystemResource;

public class  HelloApp {

   /**
    @param  args
    */
   public static void  main(String[] args) {
     // TODO Auto-generated method stub
//    BeanFactory factory;
//    factory = new XmlBeanFactory(new FileSystemResource("src/test/helloworld/hello.xml"));
     // 使用不同的方法得到bean. (BeanFactory or ApplicationContext)
     ApplicationContext context =  new  ClassPathXmlApplicationContext( "test/helloworld/hello.xml" );
    
    
     GreetingService greetingService = (GreetingService) context.getBean( "greetingService" );
//    GreetingService greetingService = (GreetingService) factory.getBean("greetingService");
     greetingService.sayGreeting();
   }

}

q有重要的配|文件如?hello.xml

<?

xml version = "1.0" encoding = "UTF-8" ?>

<!

DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

"http://www.springframework.org/dtd/spring-beans.dtd" >

<

beans >

< bean id = "greetingService"

class = "test.helloworld.GreetingServiceImpl" >

< property name = "greeting" >

< value > ice rain ! </ value >

</ property >

</ bean >

</

beans >

呵呵p么简?实现?greeting 属性的 Ioc.

q是Spring 两大基本支柱其一的工作原? 关于AoP的内?在这里不作讨?因ؓ现在我用AoP的地方不是很?单的应用是很单的?^_^.

下面一我们来看看 在spring包装下的jdbc讉K. 详细情况也可?b>参考这?/a>



junky 2006-05-23 19:37 发表评论
]]>
Spring框架学习前言---我的开源框架用心得体?http://www.tkk7.com/junky/archive/2006/05/17/46514.htmljunkyjunkyTue, 16 May 2006 16:26:00 GMThttp://www.tkk7.com/junky/archive/2006/05/17/46514.htmlhttp://www.tkk7.com/junky/comments/46514.htmlhttp://www.tkk7.com/junky/archive/2006/05/17/46514.html#Feedback0http://www.tkk7.com/junky/comments/commentRss/46514.htmlhttp://www.tkk7.com/junky/services/trackbacks/46514.html 目的Q?/strong>
在实际项目中ZE_性以及团队开发技能我一直没考虑采用Spring框架Q最q有旉p划学习Spring框架Qؓ以后的项目开发做相关的技术储备?/p>


回顾Q?/strong>
开源框架在以前的项目中用过不少Q?struts,webwork,hibernate,前两者属于web框架Q后者属于ORM框架Q这些框架基本都是侧重于应用的某个层面,不能UC为J2EE全面的框Ӟ往往是需要和其他框架相结合,我开发的目采用q如下组合,有的Ҏ没有框Ӟ只是自己做了设计装
a、servlet+jdbc,
b、servlet+jsp+javabean+jdbc,
c、struts+BD+DAO ,
d、webwork+ejb+hibernate

使用体会Q?/strong>

 a、b׃要说了,那时候的代码l构真是天马行空Q我当时初学Q维护公怸个项目代码,1个jsp实现一个模块所有功能,我花了好长时间才 L代码?br />  时代L向前发展的,慢慢的系l结构层ơ上是越来越清晰Q开发效率也来高Q维护也来容易(Z一定的培训成本Q?br /> 
 相对而言Z设计理念来讲Q个人更喜欢webwork+hibernate框架l合?/font> 

 常有论同{开发层面框架的优缺点,我所属品的另外一个项目团队曾lؓ目后箋开?应该采用strutsq是webwork争论的不可开交, 其实个h认ؓstruts,webwork都是非常好的web框架Q都有自w的优缺点:
 struts开创web MVC框架之先治I2003Q?004q开发的目基本都是采用struts框架Q当时招聘h的时候常问会不会strutsQ会基本招了 )Q实际MVC设计理念很早提ZQ在j2SE中有很多使用之处Q但当时没有一个web框架开发中很好的诏彻该设计理念Q直到struts 出现Q可能有Q只是没有apache更引人注意)?br />
 struts优点使用用户多,相关技术文比较全面,开发遇到的问题相关案例也比较多、比较容易解冻I框架更加E_(q一炚w帔R要)?br /> 
 webwork相对于struts来讲Q的有不少优异之处Q(也是情理之中的事Q后发布的框架如果再没有优点别h也不会用)
 个h认ؓ在开发上主要有以下几点:

 1、页面数据封装成值对象功能比struts强大Qwebwork采用ognlcd转化?br /> struts只能对简单类型的数据对象以及文g对象装成值对? 而webwork装的值对象基本没有限Ӟ值对象属性还可以是List,Mapq些对象Q这个特性在我们开发一些批量数据、复杂数据处理时非常方便Q,减少很多代码量,代码非常整洁?br /> 
 2、拦截器功能
 拦截器是webwork的一个亮点,实际上也是业界比较流行的AOP的一个体玎ͼ在实际开发中你可以配|默认的拦截器, 也可以ؓ单独的模块指定特定的拦截器,q且可自定义拦截器,action执行前后拦截都可以。?br /> 
 3、单元测试比较方?br /> 最早用struts框架开发测试时Q相关的单元试基本是不好做的,无法qweb环境Q测试都是只做集成测试、系l测试?br /> 使用webwork可以单对action相关属性赋|可以相关的单元测试,当然前提是在对应action中没有引用web环境相关的对象。?br /> 其实webwork框架核心q是xwork框架Q最早框架用在C/Sl构下,webwork只是xwork的一个在web环境的实玎ͼ只是ActionContext 上下文发生了变化Q所以说action能够做到qweb环境也是情理之中的?/p>


4、配|文?br />webwork配置文g可以采用引用、承其他配|文件方式,在团队开发一般都是分模块开发,q样比较方便Q配|管理更ҎQ不会冲H?br />
5、模板技术集?br /> 我在实际应用目中是采用velocity模板做视囑ֱ玎ͼ因ؓ在对应版本的webwork框架中和velociy集成的相当好Q比较方便,
 比直接写jsp代码更整z、同时利用velocity模板Ҏ结合每个action的配|文Ӟ可实现比较通用的页面查询、录入等视图的展现?br /> 而struts是没有相x杉K成,不过struts的tag相对而言比webwork的tag好用Qwebwork如果视图是jspcdQ相关的tag真的比较ȝ
 虽然tag 库很丰富Q这也是我ؓ什么用velocity做视囄原因 。?br /> 
6?框架的效验功?br /> 老实_两者框架的效验功能都比较麻烦,相对而言webwork更加ȝ点,配置较多Q验证接口实现太ȝQ我实际目使用中还?br /> 自定义了相关后台验证接口Q?要验证的相关action只要实现相关接口卛_Q相x截器负责拦截验证Q?br /> 大部分的效验Ҏ配置数据以及html对象自定义属性通过javascript通用效验Q实际上现在ZXmlHttp的ajax技术应用成熟的?br /> 后台验证接口的用途会逐渐淡化?
 
 说明上述比较版本?struts 1.0 /webwork 2.1.6Q后lstruts框架扩展很多功能Q不是很了解Q可能和上诉描述不一定很d?br /> 
 现在两者已l合qӞ希望能结合两者的优势Q发展出更好web框架?br /> 
7、关于Hibernateq是DAO模式Q个人徏议采用hibernate+DAO盔R合的模式Qhibernate占主导地位?br /> 虽然DAO模式通过自动生成代码效率不会低,但如果需求变更就比较ȝQ维护修改代码较多,试工作量也较大Q 但Hibernate不是万能的,在一些必要的应用q是采用DAO模式Q特别是性能相关的部分?
 
 
 废话一大堆Q也把我的工作回顾了一遍,呵呵Q这两天单了解Spring框架Q个人感觉Spring更像一个全面的J2EE框架解决Ҏ, 希望能够有时间系l的学习一把,大家有兴的请多多交?我会我的学习心得和大家分n?/p>

junky 2006-05-17 00:26 发表评论
]]>
վ֩ģ壺 99xxooƵѹۿ| Ʒһ߹ۿ| ޹ƷþѾ| Ʒ޳AA߹ۿ| ޾Һվ| 㽶Ƶ߹ۿ| ŮƵվ| ĻӰȫѰ| ȫƵ߹ۿ| Ʒɫѿ| պһƵ| ޾Ʒվ߹ۿ޹ | ŷƵѹ| ѻɫӰ߹ۿ| aëƬ| һػƴƬ߹ۿ | һһƬѲ| ޾ƷƬ߹ۿƷĻ| AVר߲| þ99޾Ʒۿ| ޹˾Ʒԭ| ĻۺϾþۺ| ձƷþþþþþþ| 99þ޾ƷѶ| ձһձһ岻 | ߹ۿ| ޹˾þ99Ʒ| һˮëƬѿ| Ļѵַվ| Ƶ| йڶѲ| þþþѿ| ޹ƷҹӰ| aëƬa| ȫѹɫһ| ɫݺվ| պѸƬ| žžۺAVһ| Ƶ| ëƬ18ŮëƬѿ| ޾ƷӰ|