1. 程式人生 > >Spring初級知識學習(2)

Spring初級知識學習(2)

AOP(面向切面程式設計)用來做安全驗證,記錄日誌,效能檢驗等等。

代理模式:對進行操作的物件的物件的代理。

代理物件和被代理物件:

代理分為靜態代理和動態代理,靜態代理是指在編譯階段就能確定代理物件的被代理物件,代理類需要和被代理類一一對應。

動態代理指在執行階段確定代理物件的被代理物件(一個代理類可以確定多個被代理類)。

靜態代理的實現:

    1、定義代理類,代理類應該和被代理類實現同一個介面並封裝被代理物件

   2、通過代理物件去代替被代理物件完成業務

動態代理:在執行階段動態的確定代理物件和被代理物件的協議,代理類只有一個,動態代理是基於反射的基礎之上實現的。反射是指通過獲得類的Class例項,可以得到該類的內部資訊包括例項化。

正常建立學生物件是通過Student s = new Student();

s.setAge(10);

反射是這樣的:Class c = Student.class;//每個類裡面都有一個靜態的常量。class.

c.getClassLoader();//獲得載入類器

Student s1 = (Student)c.newInstance();//建立新的例項。這個newInstance呼叫的是無參構造。所以必須有無參構造。

大Class當然也可以通過類名來獲得,也可以通過物件來獲得,像上面的Class c1 = s.getClass().

Field fs[] = c.getFields();//獲得所有的屬性名字,反射的類多在java.lang.reflect包裡。.Field

for(int i = 0 ;i<fs.length;i++){

   System.out.println(fs[i].getName());//只能打印出共有的屬性哈。public那種

}

Method ms[] = c.getMethods();//java.lang.reflect.Method

for(int i = 0 ;i<ms.length;i++){

   System.out.println(ms[i].getName());//只能打印出共有的屬性哈。public那種

}

c.getField(String fieldname);//獲得某個欄位的值。

Class c = Student.class;

Student obj = (Student)c.newInstance();

c.getMethod("setAge",int.class).invoke(obj,new Integer[]{2});//通過Class的例項的方法getMethod();第一個引數傳方法名:setAge,字串型的呀。第二個引數傳引數型別的class.因為setAget(int aget);方法invoke的第一個引數obj是要呼叫哪個物件例項的方法 ,這個是物件的例項。第二個引數是呼叫setAge時引數的值。這裡是2.

System.out.println(obj.getAge());//顯示為2

學反射是為了學習動態代理。

動態代理第一步:定義代理類,代理類實現InvocationHandler,實現invoke方法,並封裝被代理物件,建立帶引數構造把被代理物件傳進去啊。被代理物件為Object型別。

StudentDaoImp dao = new StudentDaoImp();

StudentDaoService daoService = new StudentDaoServiceImp(dao);

//動態代理是基於介面的代理

DynamicProxy dp = new DynamicProxy(daoSerivice);

//生成代理物件

StudentDaoSerivce service = (StudentDaoService)Proxy.newProxyInstance(StudentDaoServiceImp.class.getClassLoader(),//被代理物件的類的載入器

                                                                                                StudentDaoServiceImp.class.getInstances(),//被代理類所實現的全部介面

                                                                                                dp);

service.delete(new Student());

AOP:Aspact Object Programming面向切面程式設計。切面是指用來處理安全驗證,效能測試,和記錄日誌的類。我們叫做切面。切面也是一個類。一個抽象化的叫法。屬於切面的類中有方法可以橫切業務邏輯類的方法。

AOP代理有JDK動態代理或者CGLIB代理。前者是對介面的代理,後者是對類的代理。

在ApplicationContext.xml中進行AOP的配置

<bean name="myAspect" class="com.ts.aspect.MyAspect"></bean>

<aop:config>

     <aop:pointcut expression="excution(*  com.ts.service.imp.Student.*(..))"  id="pcMethod"/>///////////星的位置表示關注點要橫切的方法的返回值型別。*表任意型別。*後面是空格,再後面是要橫切的類的包或者類。類的*表示這個類的所有方法都要橫切。括號裡的點點表示任意個引數,如果括號裡是空的,表示呼叫無參構造,也可以指定引數的型別。注意啊。id是不能重的。給id起一個名標識唯一。

上面是連線點。下面是通知。

     <aop:aspect   id="aspect"  ref="myAspect">///////把上面定義的切面引入進來

             <aop:after method="doAfter" pointcut-ref="pcMethod"/>

            <aop:before method="doBefore" pointcut-ref="pcMethod"/>///////pointcut-reft指定上面定義的pointcut的id.

    </aop:aspect>

</aop:config>

spring有一個JoinPoint。把這個當做引數傳到切面的方法中,可以通過jp.getSignature().getName()得到切面方法的名字。可以通過jp.getArgs()得到切面方法的引數陣列。

如果是doAround.中間還可以傳一個ProceedingJoinPoint型別的引數。

切面型別中有如下切面方法 。

public void doAround(ProceedingJointPoint pjp){

long time1  = System.currentTimeMillis();

pjp.proceed();

long time2 = System.currentTimeMillis();

System.out.println("執行"+pjp.getSignature().getName()+"()方法共耗時"+(time2-time1)+"毫秒");

Spring是一個強大的框架,它對Struts提供也支援,也對Hibernate提供了支援。只需要提供相關的jar包就行了。

在Spring中進行事務管理器的配置。

下面定義了一個Spring的sessionFactory的Bean。

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

<property name="configLocation" value="file:src/hibernate.cfg.xml">

</property>

</bean>

<!--配置事務管理器物件-->

<bean name="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">

     <!--注入sessionFactory物件 -->

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

</bean>

<!-- 配置納入事務管理中的方法--!>

<tx:advice id="txAdvice" transaction-manager="transactionManager">

      <tx:attributes>

                <!--需要開啟事務管理的時候自動開啟---!>

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

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

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

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

      </tx:attributes>

</tx:advice>

<aop:config>

<!--需要事務連線點---!>

    <aop:pointcut expression="execution(* com.ts.service.imp.*.*(..))" id="pcMethod"/>

<!--需要通知---!>

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

</aop:config>