facade模式:就是中關(guān)村攢機(jī)者的角色,他負(fù)責(zé)與多個(gè)零件供銷商交互并將這些零件組裝起來(lái)交給最終客戶。
struts與spring集成的兩種方式:
第一種是在struts的Action的execute方法中調(diào)用spring的applicationContext去獲得Manager對(duì)象,這里的Action自身沒(méi)有用到spring的思想,Action無(wú)法作為Spring中的JavaBean進(jìn)行配置,相應(yīng)代碼如下:
????? ServletContext application = this.getServlet().getServletContext();
????? WebApplicationContext wapp = (WebApplicationContext)WebApplicationContextUtils.getWebApplicationContext(application);
???? //WebApplicationContext wapp = (WebApplicationContext)application.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
???? StudentManager studentManager = (StudentManager)wapp.getBean("studentManager");
? 另外,spring為集成struts而提供了一個(gè)ContextLoaderPlugIn插件,其作用在于:創(chuàng)建一個(gè)ApplicationContext對(duì)象,并將這個(gè)對(duì)象存儲(chǔ)在ServletContext中,以后在ActionSupport中就可以調(diào)用getWebApplicationContext來(lái)獲得這個(gè)ApplicationContext對(duì)象了,這并沒(méi)有讓我感覺(jué)有多大的好處,示例代碼如下:
??? Enumeration e = application.getAttributeNames();
??? while(e.hasMoreElements())
??? {
??????? String attributeName = (String)e.nextElement();
??????? String objClassName = application.getAttribute(attributeName).getClass().getName();
??????? try
??????? {
?????????? response.getWriter().println(attributeName + ":" + objClassName + "<br>");
??????? }catch(Exception ex){}
??? }
??? StudentManager studentManager = this.getWebApplicationContext().getBean("studentManager"));
第二種是將struts的Action作為spring的一個(gè)JavaBean進(jìn)行配置,在Action里面只需要定義一個(gè)Manager變量和相應(yīng)的setter/getter方法,就可以通過(guò)spring為其注入一個(gè)Manager對(duì)象。這種方式太復(fù)雜,很牽強(qiáng),個(gè)人覺(jué)得沒(méi)有什么實(shí)際意義,建議大家不必花費(fèi)時(shí)間去學(xué)習(xí)。
spring與hibernate整合的原理:
class MyController extend simpleformcontroller
{
?public MyController()
?{
??setCommandClass(Studnet.class);
?}
}
首先回憶使用hibernate的步驟:
1.創(chuàng)建和配置Configuration對(duì)象,配置Congiuration對(duì)象可以通過(guò)hibernate.properties或hiberate.cfg.xml文件,也可以完全采用如下的編程方式:
????? configuration = new Configuration()
????? configuration.addClass(Student.class)
???????????? //.addFile("Student.hbm.xml")
???????????? //.addResource("/Student.hbm.xml")
???????????? .setProperty("show_sql","true");
2.由configuration創(chuàng)建出SessionFactory對(duì)象:????????????
??? SessionFactory sf = configuration.buildSessionFactory();
3.通過(guò)SessionFactory獲得session對(duì)象,然后進(jìn)行CRUD操作:
??? Session session = sf.openSession();
??? session.save()\delete\update\load\
??? session.close();
使用spring集成hibernate的第一步就是借助spring的配置創(chuàng)建出SessionFactory對(duì)象
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
?<property name="mappingResource?>
??<list>
???<value>xx.hbm.xml</value>
???<value>yyy.hbm.xml</value>
??<list>
?</Property>
?<property name="hibernateProperties">
??<props>
???<prop key="show_sql">true</prop>
??<props>
?</property>
?<property name="datasource"><ref locale=""/></property>
</bean>
在LocalSessionFactoryBean內(nèi)部完全采用編程方式來(lái)配置configuration對(duì)象,而不再通過(guò)hibernate.properties或hiberate.cfg.xml配置文件,帶著大家查看了LocalSessionFactoryBean的源代碼。
有了SessionFactory,我們接著就可以通過(guò)spring將這個(gè)SessionFactory注入到DAO類中,配置如下:
<bean id="studentDAO" class="cn.itcast.StudentDAO">
?<property name="sessionFactory">
??<ref bean="sessionFactory" />
?</property>
</bean>
相應(yīng)的調(diào)用程序代碼示意如下:
class StudentDAO
{
?sessionFactroy;
?void setSessionFactory(sessionFactory)
?{
??this.sessionFactory = sessionFactory;
?}
?insert(User user)
?{
??sessionFactory.openSession();//累
??session.save(user);
??session.close();//累
?}
}
我們還有自己openSession和getSession,這是不是很累呢?為此,spring又提供了一個(gè)配置類hibernateTemplate,它可以幫助我們?nèi)penSession和closeSession,這個(gè)配置類能夠openSession,顯然它一定要有SessionFactory的引用。
<bean id="hibernateTemplate" class="HibernateTemplate">
?<property name="sessionFactory">
??<ref bean="sessionFactory" />
?</property>
</bean>
遵循spring的IOC思想,我們接著還要將HibernateTemplate注入到DAO類中,配置如下:
<bean id="studentDAO" class="cn.itcast.StudentDAO">
?<property name="hibernateTemplate">
??<ref bean="hibernateTemplate" />
?</property>
</bean>
class StudentDAO
{
?hibernateTemplate;
?void sethibernateTemplate(hibernateTemplate)
?{
??this.hibernateTemplate = hibernateTemplate;
?}
?insert(User user)
?{
??hibernateTemplate.save(user);//我們不再openSession和closeSession,不是很爽嗎?
?}
}
另外,spring還提供了一個(gè)HibernateSuport類,它可以通過(guò)注入的SessionFactory返回一個(gè)HibernateTemplate,我們的DAO類繼承這個(gè)HibernateSupport,也可以獲得HibernateTemplate對(duì)象進(jìn)行CRUD操作,配置及示意代碼如下:
<bean id="studentDAO" class="cn.itcast.StudentDAO">
?<property name="sessionFactory">
??<ref bean="sessionFactory" />
?</property>
</bean>
class StudentDAO extends HibernateSuport
{
?/*hibernateTemplate;
?void gethibernateTemplate()
?{
??return hibernateTemplate;
?}
?sessionFactroy;
?void setSessionFactory(sessionFactory)
?{
??this.sessionFactory = sessionFactory;
??hibernateTemplate = new HibernateTemplate(sessionFactory);
?}*/
?
?
?insert(User user)
?{
??getHibernateTemplate().save(user);
?}
}
?
最后由王澤佑提問(wèn)引出spring mvc的注冊(cè)綁定的詳細(xì)講解:
在spring幫助文檔中搜索editor,可以看到有關(guān)注冊(cè)綁定的信息,CustomDateEditor是沒(méi)有被自動(dòng)注冊(cè)的,需要用戶在initBinder方法內(nèi)部調(diào)用,示例代碼如下:
protected void initBinder(
??????? HttpServletRequest request,
??????? ServletRequestDataBinder binder)
??????? throws ServletException {
??????? binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy/MM/dd"),true));
??? }
一種替換的方式及registerCustomEditor底層的實(shí)現(xiàn)內(nèi)幕:
調(diào)用BaseCommandController.setPropertyEditorRegistrars()方法,顯然這可以作為controller的屬性進(jìn)行配置。
class MyPropertyEditorRegistrar
{
?void registerCustomEditors(PropertyEditorRegistry registry)
?{
??reguistry.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
?}
}
關(guān)于Date數(shù)據(jù)校驗(yàn)的問(wèn)題:通過(guò)在struts幫助文擋的Validator幫助頁(yè)面中搜索validate,是可以搜索到DateValidator的配置幫助的。
如果注冊(cè)了DateEditor,數(shù)據(jù)成功轉(zhuǎn)換成Date類型的字段,那么隨后的的Validator框架就沒(méi)必要對(duì)這個(gè)Date字段進(jìn)行校驗(yàn)了,因?yàn)閂alidator是對(duì)已裝配到Bean中的字符串類型的字段進(jìn)行校驗(yàn),而數(shù)據(jù)都已經(jīng)成功裝配進(jìn)了Date字段中,哪還有校驗(yàn)的必要。框架把數(shù)據(jù)裝配到formbean里面,Validator從Formbean里面拿數(shù)據(jù)進(jìn)行校驗(yàn)。
<bean id="myController class="cn.itcast.MyController">
?<property key="commandClass">
??<value>cn.itcast.Student</value>
?</prperty>
</bean>
上面的配置信息相當(dāng)于下面的一段代碼,這其中就涉及到了屬性綁定的問(wèn)題,要把字符串"cn.itcast.Student"轉(zhuǎn)換成Class對(duì)象。
Class clazz = Class.forName("cn.itcast.Student");
setCommandClass(clazz);
小記:通過(guò)spring配置文件中的<import>元素的resource屬性可以導(dǎo)入更多的配置文件,實(shí)現(xiàn)信息分散配置的目的。?