Spring學習筆記

課程內容

1.     面向接口(抽象)編程的概念與好處

2.     IOC/DI的概念與好處

a)     inversion of control

b)     dependency injection

3.     AOP的概念與好處

4.     Spring簡介

5.     Spring應用IOC/DI(重要)

a)     xml

b)     annotation

6.     Spring應用AOP(重要)

a)     xml

b)     annotation

7.     Struts2.1.6 +Spring2.5.6 + Hibernate3.3.2整合(重要)

a)     opensessionInviewfilter(記住,解決什麼問題,怎麼解決)

8.     Spring JDBC

面向接口編程(面向抽象編程)

1.     場景:用戶添加

2.     Spring_0100_AbstractOrientedProgramming

a)     不是AOP:Aspect Oriented Programming

3.     好處:靈活

什麼是IOC(DI),有什麼好處

1.     把自己new的東西改爲由容器提供

a)     初始化具體值

b)     裝配

2.     好處:靈活裝配

Spring簡介

1.     項目名稱:Spring_0200_IOC_Introduction

2.     環境搭建

a)     只用IOC

               i.         spring.jar , jarkata-commons/commons-loggin.jar

3.     IOC容器

a)     實例化具體bean

b)     動態裝配

4.     AOP支持

a)     安全檢查

b)     管理transaction

Spring IOC配置與應用

1.     FAQ:不給提示:

a)     window – preferences – myeclipse – xml – xml catalog

b)     User Specified Entries – add

                i.         Location:       D:\share\0900_Spring\soft\spring-framework-2.5.6\dist\resources\spring-beans-2.5.xsd

               ii.         URI:             file:///D:/share/0900_Spring/soft/spring-framework-2.5.6/dist/resources/spring-beans-2.5.xsd

              iii.         KeyType:      Schema Location

             iv.         Key:              http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

2.     注入類型

a)     Spring_0300_IOC_Injection_Type

b)     setter(重要)

c)     構造方法(可以忘記)

d)    接口注入(可以忘記)

3.     id vs. name

a)     Spring_0400_IOC_Id_Name

b)     name可以用特殊字符

4.     簡單屬性的注入

a)     Spring_0500_IOC_SimpleProperty

b)     <property name=… value=….>

5.     <bean 中的scope屬性

a)     Spring_0600_IOC_Bean_Scope

b)     singleton 單例

c)     proptotype 每次創建新的對象

6.     集合注入

a)     Spring_0700_IOC_Collections

b)     很少用,不重要!參考程序

7.     自動裝配

a)     Spring_0800_IOC_AutoWire

b)     byName

c)     byType

d)     如果所有的bean都用同一種,可以使用beans的屬性:default-autowire

8.     生命週期

a)     Spring_0900_IOC_Life_Cycle

b)     lazy-init (不重要)

c)     init-method destroy-methd 不要和prototype一起用(瞭解)

9.     Annotation第一步:

a)     修改xml文件,參考文檔<context:annotation-config/>

10.  @Autowired

a)     默認按類型by type

b)     如果想用byName,使用@Qulifier

c)     寫在private field(第三種注入形式)(不建議,破壞封裝)

d)     如果寫在set上,@qualifier需要寫在參數上

11.  @Resource(重要)

a)     加入:j2ee/common-annotations.jar

b)     默認按名稱,名稱找不到,按類型

c)     可以指定特定名稱

d)     推薦使用

e)     不足:如果沒有源碼,就無法運用annotation,只能使用xml

12.  @Component @Service @Controller @Repository

a)     初始化的名字默認爲類名首字母小寫

b)     可以指定初始化bean的名字

13.  @Scope

14.  @PostConstruct = init-method; @PreDestroy = destroy-method;

 

什麼是AOP

1.     面向切面編程Aspect-Oriented-Programming

a)     是對面向對象的思維方式的有力補充

2.     Spring_1400_AOP_Introduction

3.     好處:可以動態的添加和刪除在切面上的邏輯而不影響原來的執行代碼

a)     Filter

b)     Struts2的interceptor

4.     概念:

a)    JoinPoint  釋意:切面與原方法交接點 即 切入點

b)     PointCut  釋意:切入點集合

c)     Aspect(切面)釋意:可理解爲代理類前說明

d)     Advice 釋意:可理解爲代理方法前說明例如@Before

e)     Target  釋意:被代理對象 被織入對象

f)      Weave  釋意:織入

Spring AOP配置與應用

1.     兩種方式:

a)     使用Annotation

b)     使用xml

2.     Annotation

a)     加上對應的xsd文件spring-aop.xsd

b)     beans.xml <aop:aspectj-autoproxy/>

c)     此時就可以解析對應的Annotation了

d)     建立我們的攔截類

e)     用@Aspect註解這個類

f)      建立處理方法

g)     用@Before來註解方法

h)     寫明白切入點(execution …….)

i)      讓spring對我們的攔截器類進行管理@Component

3.     常見的Annotation:

a)     @Pointcut  切入點聲明以供其他方法使用 , 例子如下:

 

@Aspect

@Component

public class LogInterceptor {

   

    @Pointcut("execution(public * com.bjsxt.dao..*.*(..))")

    public void myMethod(){}

 

    @Around("myMethod()")

    public voidbefore(ProceedingJoinPoint pjp) throws Throwable{

       System.out.println("method before");

       pjp.proceed();

    }

    @AfterReturning("myMethod()")

    public void afterReturning() throws Throwable{

       System.out.println("method afterReturning");

    }

    @After("myMethod()")

    public void afterFinily() throws Throwable{

       System.out.println("method end");

    }

        }

 

b)     @Before 發放執行之前織入

c)     @AfterReturning 方法正常執行完返回之後織入(無異常)

d)     @AfterThrowing 方法拋出異常後織入

e)     @After 類似異常的finally

f)      @Around 環繞 類似filter , 如需繼續往下執行則需要像filter中執行FilterChain.doFilter(..)對象一樣 執行 ProceedingJoinPoint.proceed()方可,例子如下:

@Around("execution(* com.bjsxt.dao..*.*(..))")

        public voidbefore(ProceedingJoinPoint pjp) throws Throwable{

              System.out.println("method start");

              pjp.proceed();//類似FilterChain.doFilter(..)告訴jvm繼續向下執行

}

4.     織入點語法

a)     void !void

b)     參考文檔(* ..)

如果execution(* com.bjsxt.dao..*.*(..))中聲明的方法不是接口實現則無法使用AOP實現動態代理,此時可引入包” cglib-nodep-2.1_3.jar” 後有spring自動將普通類在jvm中編譯爲接口實現類,從而打到可正常使用AOP的目的.

5.     xml配置AOP

a)     把interceptor對象初始化

b)     <aop:config

               i.         <aop:aspect …..

1.     <aop:pointcut

2.     <aop:before

例子:

<beanid="logInterceptor"class="com.bjsxt.aop.LogInterceptor"></bean>

    <aop:config>

       <!-- 配置一個切面 -->

       <aop:aspectid="point" ref="logInterceptor">

           <!-- 配置切入點,指定切入點表達式 -->

           <!-- 此句也可放到 aop:aspect標籤外依然有效-->

           <aop:pointcut

              expression=

              "execution(public* com.bjsxt.service..*.*(..))"

              id="myMethod"/>

           <!-- 應用前置通知 -->

           <aop:beforemethod="before"pointcut-ref="myMethod"/>

           <!-- 應用環繞通知需指定向下進行 -->

           <aop:aroundmethod="around"pointcut-ref="myMethod"/>

           <!-- 應用後通知 -->

           <aop:after-returningmethod="afterReturning"

              pointcut-ref="myMethod"/>

           <!-- 應用拋出異常後通知 -->

           <aop:after-throwingmethod="afterThrowing"

              pointcut-ref="myMethod"/>

           <!-- 應用最終通知  -->

           <aop:aftermethod="afterFinily"

              pointcut="execution(public* om.bjsxt.service..*.*(..))"/>

       </aop:aspect>

</aop:config>

Spring整合Hibernate

1.     Spring 指定datasource

a)     參考文檔,找dbcp.BasicDataSource

               i.         c3p0

              ii.         dbcp

            iii.         proxool

b)     在DAO或者Service中注入dataSource

c)     在Spring中可以使用PropertyPlaceHolderConfigure來讀取Properties文件的內容

2.     Spring整合Hibernate

a)     <bean .. AnnotationSessionFactoryBean>

               i.         <property dataSource

              ii.         <annotatedClasses

b)     引入hibernate 系列jar包

c)     User上加Annotation

d)     UserDAO或者UserServie 注入SessionFactory

e)     jar包問題一個一個解決

3.     聲明式的事務管理

a)     事務加在DAO層還是Service層?Service層(多個dao操作時?)

b)     annotation

               i.         加入annotation.xsd

              ii.         加入txManager bean

            iii.         <tx:annotation-driven

例如: <bean id="transactionManager"                   class="org.springframework.orm.hibernate3.HibernateTransactionManager">

          <propertyname="sessionFactory">

            <refbean="sessionFactory" />

          </property>

    </bean>

   <tx:annotation-driventransaction-manager="transactionManager"/>

            iv.         在需要事務的方法上加:@Transactional

              v.         需要注意,Hibernate獲得session時要使用SessionFactory.getCurrentSession不能使用OpenSession

c)     @Transactional詳解

               i.         什麼時候rollback

1.     運行期異常,非運行期異常不會觸發rollback

2.     必須uncheck (沒有catch)

3.     不管什麼異常,只要你catch了,spring就會放棄管理

4.     事務傳播特性:propagation_required

例如:@Transactional(propagation=Propagation.REQUIRED)等同於(@Transactional)

作用,一個方法聲明瞭@Transactional事務後,其內再調用的方法不需要再聲明@Transactional.

5.     read_only

例如:@Transactional(propagation=Propagation.REQUIRED,readOnly=true)

當方法聲明readOnly=true,該方法及其調用的方法內都不執行insert update

d)     xml(推薦,可以同時配置好多方法)

               i.         <bean txmanager

              ii.         <aop:config

1.     <aop:pointcut

2.     <aop:advisor pointcut-ref advice-ref

            iii.         <tx:advice: idtransaction-manager =

            iv.         <propertyname="packagesToScan">  可定義掃描目標包下所有實體類

例如: <bean id="sessionFactory"

                            class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

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

          <propertyname="hibernateProperties">

                 <props>

                 <propkey="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>

                      <propkey="hibernate.show_sql">true</prop>  

                 </props>

           </property>

           <!--

          <propertyname="annotatedClasses">

               <list>

                     <value>com.bjsxt.model.TestUser</value>

                     <value>com.bjsxt.model.Log</value>

               </list>

          </property>

           -->

           <!-- 將參數名稱設爲packagesToScan可定義掃描目標包下所有實體類 -->

           <propertyname="packagesToScan">

               <list>

                     <value>com.bjsxt.model</value>

               </list>

           </property>

    </bean>

<bean id="transactionManager"

       class="org.springframework.orm.hibernate3.HibernateTransactionManager">

        <propertyname="sessionFactory">

            <refbean="sessionFactory" />

       </property>

    </bean>

   

    <aop:config>

       <aop:pointcut

                 expression="execution(public* com.bjsxt.service..*.*(..))"

                 id="myServiceMethod"/>

       <aop:advisor pointcut-ref="myServiceMethod"advice-ref="txAdvice"/>

   </aop:config>

   

    <tx:adviceid="txAdvice" transaction-manager="transactionManager">

       <tx:attributes>

           <tx:method name="save*" propagation="REQUIRED"/>

           <tx:method name="add*" propagation="REQUIRED"/>

           <tx:method name="update*" propagation="REQUIRED"/>

           <tx:method name="del*" propagation="REQUIRED"/>

           <tx:method name="cancel*" propagation="REQUIRED"/>

           <tx:method name="*" read-only="true" />

       </tx:attributes>

    </tx:advice>

e)     HibernateTemplate、HibernateCallback、HibernateDaoSupport(不重要)介紹

               i.         設計模式:TemplateMethod(模板方法)

              ii.         Callback:回調/鉤子函數

            iii.         第一種:(建議)

1.     在spring中初始化HibernateTemplate,注入sessionFactory

<bean id="hibernateTemplate"

      class="org.springframework.orm.hibernate3.HibernateTemplate">

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

</bean>

2.     DAO裏注入HibernateTemplate

private HibernateTemplate hibernateTemplate;

 

@Resource

public void setHibernateTemplate(HibernateTemplatehibernateTemplate) {

      this.hibernateTemplate= hibernateTemplate;

}

3.     save寫getHibernateTemplate.save();

public void save(TestUser testUser) {

      hibernateTemplate.save(testUser);

}

            iv.         第二種:

1.     從HibernateDaoSupport繼承(此方法不好用可忽略)

2.     必須寫在xml文件中,無法使用Annotation,因爲set方法在父類中,而且是final的

例如:

首先,新建SuperDAOImpl(使用Annotation注入--@Component):

@Component

public class SuperDAOImpl {

      privateHibernateTemplate hibernateTemplate; //此處定義由spring注入管理

      publicHibernateTemplate getHibernateTemplate() {

           returnhibernateTemplate;

      }

      @Resource

      public voidsetHibernateTemplate(HibernateTemplate hibernateTemplate) {

           this.hibernateTemplate= hibernateTemplate;

      }

}

此時,xml中必須要有:

<bean id="hibernateTemplate"

class="org.springframework.orm.hibernate3.HibernateTemplate">

      <propertyname="sessionFactory" ref="sessionFactory" />

</bean>

或者,SuperDAOImpl類寫成下面代碼:

@Component

public class SuperDAOImpl extends HibernateDaoSupport {

      @Resource(name="sessionFactory")

      public voidsetSuperHibernateTemplate(SessionFactory sessionFactory) {

           super.setSessionFactory(sessionFactory);

      }

}

對應的xml中則可省略

<bean id="hibernateTemplate"………部分

只要包含

<bean id="sessionFactory"……..部分即可

 

最後,其他類繼承SuperDaoImpl類後便可直接使用HibernateTemplate

@Component("u")

public class UserDAOImpl extends SuperDAOImpl implementsUserDAO {

      public voidsave(TestUser testUser) {

           this.getHibernateTemplate().save(testUser);

      }

}

3種方法:就是用繼承,所有的DAO extends superDAO ,superDAO裏面注入了HibernateTemplate  .....用的時候注意的是,子類和父類都用同樣的方法,xml或是annotataion

 

spring整合hibernate的時候使用packagesToScan屬性,可以讓spring自動掃描對應包下面的實體類

Struts2.1.6 +Spring2.5.6 + Hibernate3.3.2

1.     需要的jar包列表

jar包名稱

所在位置

說明

antlr-2.7.6.jar

hibernate/lib/required

解析HQL

aspectjrt

spring/lib/aspectj

AOP

aspectjweaver

..

AOP

cglib-nodep-2.1_3.jar

spring/lib/cglib

代理,二進制增強

common-annotations.jar

spring/lib/j2ee

@Resource

commons-collections-3.1.jar

hibernate/lib/required

集合框架

commons-fileupload-1.2.1.jar

struts/lib

struts

commons-io-1.3.2

struts/lib

struts

commons-logging-1.1.1

單獨下載,刪除1.0.4(struts/lib)

struts

spring

dom4j-1.6.1.jar

hibernate/required

解析xml

ejb3-persistence

hibernate-annotation/lib

@Entity

freemarker-2.3.13

struts/lib

struts

hibernate3.jar

hibernate

 

hibernate-annotations

hibernate-annotation/

 

hibernate-common-annotations

hibernate-annotation/lib

 

javassist-3.9.0.GA.jar

hiberante/lib/required

hibernate

jta-1.1.jar

..

hibernate transaction

junit4.5

 

 

mysql-

 

 

ognl-2.6.11.jar

struts/lib

 

slf4j-api-1.5.8.jar

hibernate/lib/required

hibernate-log

slf4j-nop-1.5.8.jar

hibernate/lib/required

 

spring.jar

spring/dist

 

struts2-core-2.1.6.jar

struts/lib

 

xwork-2.1.2.jar

struts/lib

struts2

commons-dbcp

spring/lib/jarkata-commons

 

commons-pool.jar

..

 

struts2-spring-plugin-2.1.6.jar

struts/lib

 

2.     BestPractice:

a)     將這些所有的jar包保存到一個位置,使用的時候直接copy

3.     步驟

a)     加入jar包

b)     首先整合Spring + Hibernate

               i.         建立對應的package

1.     dao / dao.impl / model / service / service.impl/ test

              ii.         建立對應的接口與類框架

1.     S2SH_01

            iii.         建立spring的配置文件(建議自己保留一份經常使用的配置文件,以後用到的時候直接copy改)

            iv.         建立數據庫

              v.         加入Hibernate註解

1.     在實體類上加相應註解@Entity @Id等

在字段屬性的get方法上加--@Column(name = "表字段名")

2.     在beans配置文件配置對應的實體類,使之受管

            vi.         寫dao service的實現

           vii.         加入Spring註解

1.     在對應Service及DAO實現中加入@Component,讓spring對其初始化

2.     在Service上加入@Transactional或者使用xml方式(此處建議後者,因爲更簡單)

3.     在DAO中注入sessionFactory

4.     在Service中注入DAO

5.     寫DAO與Service的實現

          viii.         寫測試

c)     整合Struts2

               i.         結合點:Struts2的Action由Spring產生

              ii.         步驟:

1.     修改web.xml加入 struts的filter

如下:

<filter>

      <filter-name>struts2</filter-name>

      <filter-class>

           org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

      </filter-class>

</filter>

<filter-mapping>

      <filter-name>struts2</filter-name>

      <url-pattern>/*</url-pattern>

</filter-mapping>

2.     再加入spring的listener,這樣的話,webapp一旦啓動,spring容器就初始化了

如下:

<!-- 指定由spring初始化加載xml配置文件 springstruts結合必備 -->

<listener>

      <listener-class>

           org.springframework.web.context.ContextLoaderListener

           <!-- 默認尋找xml路徑:WEB-INF/applicationContext.xml-->

      </listener-class>

</listener>

 

<!--整個應用的參數服務啓動時讀取.

      可指定spring初始化文件路徑位置 -->

<context-param>

      <param-name>contextConfigLocation</param-name>

      <param-value>

           classpath*:spring/*applicationContext.xml

      </param-value>

</context-param>

3.     規劃struts的action和jsp展現

4.     加入struts.xml

a)    修改配置,由spring替代struts產生Action對象

5.     修改action配置

a)    把類名改爲bean對象的名稱,這個時候就可以使用首字母小寫了

b)    @Scope(“prototype”)不要忘記

            iii.         struts的讀常量:

1.     struts-default.xml

2.     struts-plugin.xml

3.     struts.xml

4.     struts.properties

5.     web.xml

            iv.         中文問題:

1.     Struts2.1.8已經修正,只需要改i18n.encoding = gbk

2.     使用spring的characterencoding

:

<!-- 過濾器相關配置 ========字符編碼過濾======== -->

<filter>

      <filter-name>CharacterEncodingFilter</filter-name>

      <filter-class>

           org.springframework.web.filter.CharacterEncodingFilter

      </filter-class>

      <init-param>

           <param-name>encoding</param-name>

           <param-value>UTF-8</param-value>

      </init-param>

      <init-param>

           <param-name>forceEncoding</param-name>

           <param-value>true</param-value>

      </init-param>

</filter>

3.     需要嚴格注意filter的順序

4.     需要加到Struts2的filter前面

              v.         LazyInitializationException

1.     OpenSessionInViewFilter

2.     需要嚴格順序問題

3.     需要加到struts2的filter前面

 

:

1

@Autowired @Resource都可以用來裝配bean.  都可以寫在屬性定義上,或寫在set方法上

@Autowired (srping提供的)默認按類型裝配

@Resource ( j2ee提供的 )默認按名稱裝配,當找不到(不寫name屬性)名稱匹配的bean再按類型裝配.

可以通過@Resource(name="beanName")指定被注入的bean的名稱,要是指定了name屬性,就用字段名去做name屬性值,一般不用寫name屬性.

@Resource(name="beanName")指定了name屬性,按名稱注入但沒找到bean,就不會再按類型裝配了.

@Autowired @Resource可作用在屬性定義上就不用寫set方法了(此方法不提倡);

 

 

2

      a.

Action類前加@Component,Action可由spring來管理,例子如下:

Action中寫:

@Component("u") //spring管理註解

@Scope("prototype") //多態

public class UserAction extends ActionSupportimplements ModelDriven{

      //內部屬性需要有get/set方法且需要set方法前加@Resource@Autowired

}

 

Struts2配置文件中寫

<action name="u"class="u">

 

Jsp

<form method="post"action="u.do" >

 

b.

Action中也可不加@ComponentActionstruts2-spring-plugin管理。此時,如果Action中定義的屬性有set方法@Autowired@Resource也可不寫,但是如果沒有set方法,則需要在屬性前加上@Autowired@Resource才能生效。

 

 

      3

Hibernate如果使用load來查詢數據,例如:

Service中:

public User loadById(int id) {

      returnthis.userDao.loadById(id);

}

DAO中:

public User loadById(int id) {

      return(User)this.hibernateTemplate.load(User.class, id);

}

此時,session(應該說的是Hibernatesession)在事物結束(通常是service調用完)後自動關閉。由於使用的是load獲取數據,在jsp頁面申請取得數據時才真正的執行sql,而此時session已經關閉,故報錯。

Session關閉解決方法:

web.xml中增加filter—openSessionInView,用於延長sessionjsp調用完後再關閉

如下所示:

注意:filter–openSessionInView一定要在 filter—struts2之前調用

        Filter順序先進後出!

<filter>

      <filter-name>OpenSessionInViewFilter</filter-name>

      <filter-class>

org.springframework.orm.hibernate3.support.OpenSessionInViewFilter

</filter-class>

      <init-param>

           <param-name>sessionFactoryBeanName</param-name>

           <param-value>sf</param-value>(此處默認指定的sessionFactory應爲” sessionFactory”默認可省略此行如果shring配置文件中配置的sessionFactory”sf”則此處需要寫sf  一般用不到)

      </init-param>

</filter>

<filter-mapping>

      <filter-name>OpenSessionInViewFilter </filter-name>

      <url-pattern>/*</url-pattern>

</filter-mapping>

<filter>

      <filter-name>struts2</filter-name>

      <filter-class>

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

</filter-class>

</filter>

<filter-mapping>

      <filter-name>struts2</filter-name>

      <url-pattern>/*</url-pattern>

</filter-mapping>

 

 

 

跨數據的事務管理用jta不用hibernate,用了hibernate的事務管理之後,就不需要使用try catchfinally來對異常捕獲回滾

 

 

Action及其set屬性有struts.xml自動裝配,如果struts.xml裏的actionclass屬性設爲springbeanid屬性值,則struts.xml不會自動裝配action及其set屬性,而是由spring來裝配,還有struts.xml來裝配action是通過屬性的名字來裝配的。

Spring自動化測試   opensessioninviewIntercepter

發佈了78 篇原創文章 · 獲贊 287 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章