java高新技術(二)


 

7JavaBean內省

8beanutils工具包

9註解

10泛型

11AOP


 

7JavaBean內省

 



javaBean
是一種特殊的java類主要用於傳遞數據信息,這種java類中的方法主要用於訪問私有的字段,且方法名符合某種命名規則。一個類被當做javaBean使用時,javaBean的屬性是根據方法名推斷出來的,它根本看不到java類內部的成員變量。

java
的註解
註解被用來爲程序元素設置元數據,它並不影響程序代碼的執行,即無論增加什麼註釋,程序執行都不受影響,java的註解採用@標記形式,後跟上註解類型名稱,在JDK中java.lang包中預定義了三種註解,分別是:Override,Deprecated和SuppressWarnings.
重寫
Override
Override是一個限定重寫方法的註解類型,用來指明被註解的方法必須是重寫超類方法的方法,這個註解只能用於方法上,編譯器在編譯源代碼時會檢查用@Override標註的方法是否有重寫父類的方法

警告Deprecated
Deprecated是用來標記已過時成員的註解類型,用來指明被註解的方法是一個過時的方法,不建議使用了,當編譯調用到被標註爲Deprecated的方法的類時,編譯器就會產生警告。

抑制警告SuppressWarnings
SuppressWarnings是抑制編譯器警告的註解類型,用來指明被註解的方法,變量或類在編譯時如果有警告信息,就阻止警告。

 

 

8beanutils工具包

我們在操作JavaBean的時候 我們可以用Introspector的方式來操作,但是呢這樣需要我們寫大量的代碼 。

Apache小組爲我們提供了很有用的工具包來操作JavaBean 也就是BeanUtils工具包 ,這個可以到apache.org 上面下載 commons-BeanUtils工具包,同時我們也要下載Logging也就是日誌工具包 。

 

我們下載好了BeanUtils工具包之後 打開之後 發現你面有一個docs那個就是幫助文檔 介紹了 Beanutils工具包中各種類的使用 ,這裏 我們主要用到BeanUtils類

 

BeanUtils類中的所有方法都是靜態方法 我們通過它的getPropertysetProperty方法 等等方法 這裏我們主要用到BeanUtils類

9註解


註解被用來爲程序元素設置元數據,它並不影響程序代碼的執行,即無論增加什麼註釋,程序執行都不受影響,java的註解採用@標記形式,後跟上註解類型名稱,在JDK中java.lang包中預定義了三種註解,分別是:Override,Deprecated和SuppressWarnings.
重寫
Override
Override是一個限定重寫方法的註解類型,用來指明被註解的方法必須是重寫超類方法的方法,這個註解只能用於方法上,編譯器在編譯源代碼時會檢查用@Override標註的方法是否有重寫父類的方法

警告Deprecated
Deprecated是用來標記已過時成員的註解類型,用來指明被註解的方法是一個過時的方法,不建議使用了,當編譯調用到被標註爲Deprecated的方法的類時,編譯器就會產生警告。

抑制警告SuppressWarnings
SuppressWarnings是抑制編譯器警告的註解類型,用來指明被註解的方法,變量或類在編譯時如果有警告信息,就阻止警告。

10泛型



泛型是提供給JDBC編譯器使用的,可以限定集合中的輸入類型讓編譯器擋住源程序中的非法輸入,編譯器編譯帶類型說明的集合時會去除掉"類型"信息,是程序運行效率不受影響,對於參數化的泛型類型 getClass()方法的返回值和原始類型完全一樣由於編譯生成的字節碼會議去掉泛型的類型信息,只要能跳過編譯器就可以往某個泛型集合中加入其它類型的數據。
泛型的思想是消除取用集合元素時代碼中的強制類型轉換,比如事先規定好一個集合中允許加入的具體元素類型,然後在編譯環節實現集合中添加元素的類型檢查,以防止有人將非預期類型的元素保存到集合中。
優點是類型錯誤可以在編譯時暴露出來,而不是在運行時才發作(拋ClassCastException),這有助於早期錯誤排查,並提高程序的可靠性。
注意:
(1)JDK5.0後集合類定義像Vector一樣都進行了泛型化改造,還有泛型類帶有多個類型參數,如Map<K,V>就有兩個類型參數,表示鍵-值映射。
(2)Java語言中的泛型是維護向後兼容的,即我們完全可以不採用泛型,而繼續沿用過去的做法。
(3)在高版本開發環境中編譯未啓用泛型機制的集合類應用代碼時,會輸出編譯提示信息。
11AOP
AOP:aspect oriented program.
不改變源代碼,還給類增加新的功能.(代理)
Session s = SessionFactory.openSession();
Transaction tx = s.beginTransaction();
s.save(..);
tx.commit();
s.close();
切面:aspect,要實現的交叉功能
.
通知:切面的實際實現,比較具體(細化
).
連接點:可以將通知應用到目標程序中的地點.(方法調用,異常拋出,要修改的字段
)
切入點:真正的將通知應用到目標程序中的地點
.
引入:爲類增加新的方法和屬性
.
目標對象:被通知的對象
.
代理:把通知應用給目標對象以後,創建暫新的對象,該對象即爲代理對象
.
織入:把通知應用給目標對象以後,創建暫新的對象的過程即爲織入
.
1.編譯期織入:當把java源代碼編譯成字節碼class文件時,將通知織入.需要特殊的編譯器
.
2.類裝載期織入:當把class文件載入到jvm時,將通知織入
.
3.運行期(runtime)織入
:
spring代理方式

1.接口代理(jdk的動態代理):
2.對類代理(cglib代理
):
aop聯盟
:
使用spring開發
aop:
1.引入aop聯盟類庫.(spring.jar已經內置了該包
)
2.引入cglib類庫實現對類代理.${spring解壓目錄
}/lib/cglib/*.jar

PointCut{
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
}

interface ClassFilter{
boolean isMatch(Class clazz);
}

interface Methodmatcher{
boolean matches(Method m,Class targetClass);1.
boolean isRuntime();2.
boolean matchers(Method m,Class target,Object[] args);3.
}

MethodBeforeAdvice|AfterReturningAdvice|MethodInterceptor
Advisor{

}
使用aspectj進行aop開發

1.引入aspectj類庫
${spring解壓目錄}/lib/aspectj/*.jar
2.pojo:plain old java object.
使用
pojo + xml
dao:data access object.(數據訪問對象
)

<!-- 創建目標對象
bean -->
<bean id="welcomeServiceTarget" class="cn.csdn.spring.service.WelcomeServiceImpl">
<property name="name" value="tom"/>
</bean>
<!-- 創建通知內容的
bean -->
<bean id="myMethodBeforeAdvice"class="cn.csdn.spring.advice.MyMethodBeforeAdvice"/>
<!-- 創建代理
bean
注意創建代理Bean需要有三個Property要設置,代理的接口(proxyInterfaces)也可以不寫

-->
<bean id="welcomeService"class="org.springframework.aop.framework.ProxyFactoryBean">
<!--
接口 -->
<property name="proxyInterfaces">
<list>
<value>cn.csdn.spring.service.WelcomeService</value>
</list>
</property>

<!-- 要切入的通知內容
-->
<property name="interceptorNames">
<list>
<value>myMethodBeforeAdvice</value>
</list>
</property>

<!-- 選擇目標對象
-->
<property name="target" ref="welcomeServiceTarget"/>
</bean>
//////////////////////////////////////////////
配置後置通知

1)定義通知
public class MyMethodAfterAdvice implements AfterReturningAdvice {
}
2)

<!-- 要切入的通知內容 -->
<property name="interceptorNames">
<list>
<value>myMethodBeforeAdvice</value>
<value>myMethodAfterAdvice</value>
</list>
</property>
/////////////////////////////////////////////
基於CGLIB的類代理

以前我們都是基於接口代理的:
得到對象的方式是:
WelcomeService ww=(WelcomeService) ac.getBean("welcomeService");
而現在我們將基於類進行代理
方法如下:
1)獲得類對象的方式
WelcomeServiceImpl ww=(WelcomeServiceImpl)ac.getBean("welcomeService");
2
)修改配置文件
<!-- 設置基於類的代理 -->
<property name="proxyTargetClass" value="true"/>
///////////////////////////////////////////////////////
環繞通知:

環繞通知使用:
1)定義自己的異常處理類 MyAroundMethodAdvice
2)實現 ThrowsAdvice 接口
implementsMethodInterceptor
3)添加方法環繞通知方法:


public Object invoke(MethodInvocation Invocation) throws Throwable {
// TODO Auto-generated method stub

System.out.println("Around Start!");
//
調用目標方法
Invocation.proceed();

System.out.println("Around End!");
return Invocation;
}

4
)配置文件:
添加bean
<!-- 創建環繞通知
-->
<bean id="myAroundMethodAdvice"class="cn.csdn.spring.advice.MyAroundMethodAdvice"/>
代理通知
:
<property name="interceptorNames">
<list>
<value>myAroundMethodAdvice</value>
</list>
</property>
異常通知使用:

1)定義自己的異常處理類 MyMethodException
2)實現 ThrowsAdvice 接口
implementsThrowsAdvice
3)添加方法異常通知方法:

public void afterThrowing(Method method, Object[] args, Object target,Exception ex){
System.out.println("
當前方法:"+method+",參數個數:"+args.length+",目標對象:"+target.getClass().getName()+",異常類型:"+ex.getMessage());
}

4)配置文件:

添加bean
<!-- 創建異常通知類型
-->
<bean id="myMethodException" class="cn.csdn.spring.advice.MyMethodException"/>
代理通知
:
<property name="interceptorNames">
<list>
<value>myMethodException</value>
</list>
</property>
代理通知
:
<property name="interceptorNames">
<list>
<value>myMethodException</value>
</list>
</property>
5)在實際業務邏輯中產生一個異常

靜態切入點:
切入點(advisor)包括:通知+要過濾的方法
1)配置步驟
在打招呼的接口中(GreetingService)定義方法eat()
並在實現類中,我們實現該方法,並且我們測試只給這個方法加上前置通知

2)修改配置文件
<!-- 配置靜態切入點 -->
<bean id="beforeAdvisor"class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<!-- 配置通知
-->
<property name="advice" ref="myMethodBeforeAdvice"/>
<!-- 增加要過濾的方法
-->
<property name="mappedNames">
<list>
<value>eat</value>
</list>
</property>
</bean>
3)修改代理的通知

<!-- 要切入的通知內容 -->
<property name="interceptorNames">
<list>
<!--
<value>myMethodBeforeAdvice</value>
-->
<value>beforeAdvisor</value>
<value>myMethodAfterAdvice</value>
<value>myAroundMethodAdvice</value>
<value>myMethodException</value>
</list>
</property>
引入:爲已經存在的類增加屬性和方法

目標:
1)爲目標對象添加屬性
2)爲目標對象添加方法
添加步驟:
1)定義ModifyDate接口(get、set方法)
2)實現接口,定義變量 重寫get、set方法,繼承DelegatingIntroductionInterceptor類
public class ModifyDateImpl extends DelegatingIntroductionInterceptorimplements ModifyDate {
private static final long serialVersionUID = 1L;
.......
3
)修改配置文件

1)增加引入通知(ModifyDateImpl)
<!-- 定義一個引入bean -->
<bean id="modifyDateImpl"class="cn.csdn.spring.service.ModifyDateImpl"/>
2)添加針對引入通知的默認的切入點()

<!-- 定義一個用於執行引入通知的默認切入點 -->
<bean id="defaultIntroductionAdvisor"class="org.springframework.aop.support.DefaultIntroductionAdvisor">
<constructor-arg ref="modifyDateImpl"/>
</bean>
3)在代理通知(通知攔截)中增加

<value>defaultIntroductionAdvisor</value>使之代理默認的切入點
4)調試、測試
//獲得修改類的對象

ModifyDate md=(ModifyDate)ww;
md.setModDate(Date.valueOf("2011-05-22"));
System.out.println(md.getModDate());

什麼叫Aop?
Aspect Oriented Programming 面向方面編程

特點:
OOP(面向對象編程)
基於面向對象,進行高度封裝,但是重複代碼太多

舉例 我有 20 類,每個類 5個方法。
需求:每個方法打印HelloWorld
OOP思想

1)每個方法都要 加System.out.println("HelloWorld");
2)肯定得修改源代碼

3)代碼重複量大
AOP思想 (能夠實現不改變源代碼,增加類新的功能)
1)能不能不改變 源代碼 實現打印?
2)通過 切入點 完成 代理

3)重複勞動少了
AOP 常見術語
切面:需要實現的交叉功能
連接點:應用程序執行的過程中插入切面的地點(可以是方法,異常,修改字段)
通知:交叉功能(切面)的具體實現,通知是在“連接點”插入系統
切入點:已經被通知切入的連接點
引入:允許爲已經存在的類添加新的方法或者屬性
目標對象:被通知的類,它既可以是自己編寫的類,也可以是添加定製的第三方的類。
代理:將通知應用到目標對象後產生的新的對象(代理對象)
織入:將切面應用到目標對象後產生的新的對象的“過程”,切面是在指定的連接點被織入到目標對象中
織入可以發生在對象生命週期的多個點(方法、異常)上
織入發生的時期:
編譯期:切面在目標對象編譯的時候織入
裝載期:切面在目標對象被轉載進JVM 的時候織入
運行期:切面在應用系統運行時織入(AOP將在織入切面時動態的產生委託代理對象)
AOP 的具體實現:
1)Java編寫Spring的通知
2)Spring運行的時候通知對象
3)Spring實現了AOP聯盟的接口
4)只支持方法連接點
AOP 創建代理的方式:
1)通過接口創建代理

2)通過類(cglib)創建代理
使用接口方式創建代理優於使用類創建代理

使用final的方法不能被通知


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章