泛型高級應(yīng)用
- 自定義泛型方法
package cn.imeina.web.enhancebasic.generic;
/**
* 自定義泛型方法:<T>需提前申明定義器予,才能使用
* @author gaopengfei
*
*/
public class CustomGenericMethod {
public <T> T method1(T t){
return null;
}
public <T> void method2(T t){
}
}
- 自定義泛型類
package cn.imeina.web.enhancebasic.generic;
/**
* 自定義泛型類
* @author gaopengfei
*
* @param <T>
*/
public class CustomGenericClass<T> {
public T method1(T t){
return null;
}
public void method2(T t){
}
/**
* 靜態(tài)泛型方法懊烤,必須提前申明定義
* @param t
* @return
*/
public static <T> T method3(T t){
return null;
}
/**
* 定義多個泛型:多用于map
* @param k
* @return
*/
public static <K,V> V method4(K k){
return null;
}
}
- 泛型通配符?
package cn.imeina.web.enhancebasic.generic;
import java.util.Collection;
/**
* 泛型通配符
* @author gaopengfei
*
*/
public class GenericWildcards {
/**
* 該方法只能打印泛型為string類型的數(shù)組元素
* @param strr
*/
public static void print1(Collection<String> strr){
for (String string : strr) {
System.out.println(string);
}
}
/**
* 通配符為了解決print1方法的限制而誕生
* 使用?通配符是引用類型掠拳,但是通配符因?yàn)椴淮_定類型所以不能調(diào)用和類型有關(guān)的方法例如add等方法...
* @param arr
*/
public static void print2(Collection<?> arr){
for (Object object : arr) {
System.out.println(object);
}
}
}
- 泛型的上下限
類名<? extends 類>對象名:泛型的上限(類及其子類)
類名<? super 類>對象名:泛型的下限(類及其父類)
- 泛型的定義者和泛型的使用者
- 泛型的定義者:
ArrayList<E>:類型的形式參數(shù)(形參)
ArrayList<E>:帶有泛型的類
- 泛型的使用者:
ArrayList<Integer>:類型的實(shí)際參數(shù)(實(shí)參)
ArrayList<Integer>:參數(shù)化的泛型類(ParamerizedType就是這種類型)
- 泛型的反射
Class<T> clazz;
public BaseDao() {
//得到當(dāng)前類型的帶有泛型類型的父類
//如果是public class UserDaoImpl extends BaseDao<UserInfo> implements UserDao,得到的就是BaseDao<UserInfo>
Type type = this.getClass().getGenericSuperclass();
//參數(shù)化類的泛型類型
ParameterizedType pt = (ParameterizedType) type;
//獲取實(shí)際類型參數(shù)
Type[] types = pt.getActualTypeArguments();
clazz = (Class<T>) types[0];
}
DAO模型
DAO(Data Access Object) 數(shù)據(jù)訪問對象是一個面向?qū)ο蟮臄?shù)據(jù)庫接口,數(shù)據(jù)訪問:顧名思義就是與數(shù)據(jù)庫打交道捺弦。夾在業(yè)務(wù)邏輯與數(shù)據(jù)庫資源中間殃饿。
在核心J2EE模式中是這樣介紹DAO模式的:為了建立一個健壯的J2EE應(yīng)用谋作,應(yīng)該將所有對數(shù)據(jù)源的訪問操作抽象封裝在一個公共API中。用程序設(shè)計的語言來說乎芳,就是建立一個接口遵蚜,接口中定義了此應(yīng)用程序中將會用到的所有事務(wù)方法。在這個應(yīng)用程序中奈惑,當(dāng)需要和數(shù)據(jù)源進(jìn)行交互的時候則使用這個接口吭净,并且編寫一個單獨(dú)的類來實(shí)現(xiàn)這個接口在邏輯上對應(yīng)這個特定的數(shù)據(jù)存儲
但是這樣做會發(fā)現(xiàn),因?yàn)槭遣僮鲾?shù)據(jù)庫所以多數(shù)DAO接口有著相同的CURD操作肴甸。如果每寫一個DAO都寫4個CURD代碼重復(fù)率極高寂殉,而且對應(yīng)都Impl實(shí)現(xiàn)類也同樣做相同都代碼,為了解決復(fù)用問題精簡代碼原在〔怀牛可以向上抽取
DAO模式是標(biāo)準(zhǔn)的J2EE設(shè)計模式之一.開發(fā)人員使用這個模式把底層的數(shù)據(jù)訪問操作和上層的商務(wù)邏輯分開.一個典型的DAO實(shí)現(xiàn)有下列幾個組件:
- 一個DAO工廠類文兢;
- 一個DAO接口;
- 一個實(shí)現(xiàn)DAO接口的具體類焕檬;
- 數(shù)據(jù)傳遞對象(有些時候叫做值對象)姆坚;
具體的DAO類包含了從特定的數(shù)據(jù)源訪問數(shù)據(jù)的邏輯。
注解(Annotation)
從JDK5.0開始实愚,Java提供了對元數(shù)據(jù)(MetaData)對支持兼呵,也就是Annotation注解。
Annotation其實(shí)就是代碼里對特殊標(biāo)記腊敲,用于替代配置文件击喂,傳統(tǒng)方式通過配置文件告訴類如何運(yùn)行,有類注解后開發(fā)人員可以通過注解告知類如何運(yùn)行碰辅。
在Java注解中可以通過反射獲取類中對注解懂昂,以決定如何運(yùn)行類。
- JDK中的三個注解
@Overrived:覆蓋父類方法
@Deprecated:標(biāo)識類或方法過時
@SuppressWarnings:抑制警告
- 自定義注解
- 語法
public @interface 注解名{
類型 屬性名() [default 值];
}
注解的類型必須是基本類型没宾、String凌彬、Annotation、Class循衰、Enum铲敛、及以上類型的一維數(shù)組
- 使用
@注解名(屬性=值[,屬性=值])
注:默認(rèn)情況下若無自定義value屬性,自定義注解會有默認(rèn)的一個屬性名value
注:自定義注解都屬于java.lang.annotation.Annotation類型
- 元注解:用于注解上的注解会钝,就上元注解
- @Retention:用于更改注解的存活范圍
RetentionPolicy value();
RetentionPolicy是枚舉類型伐蒋,有3個值:SOURCE、CLASS迁酸、RUNTIM - @Target:用于標(biāo)識該注解使用的范圍
ElementType[] value();
ElementType是枚舉類型先鱼,有10個值:
TYPE
FIELD
METHOD
PARAMETER
CONSTRUCTOR,
LOCAL_VARIABLE,
ANNOTATION_TYPE,
PACKAGE,
TYPE_PARAMETER,
TYPE_USE - @Documented:用于標(biāo)識該注解是否出現(xiàn)在javadoc文檔中
- @Inherited:用于標(biāo)識該注解若作用于類上是否可以被繼承
- 注解的反射
java.lang.reflect.AnnotatedEmelent:表示目前正在此 VM 中運(yùn)行的程序的一個已注釋元素。該接口允許反射性地讀取注釋奸鬓。由此接口中的方法返回的所有注釋都是不可變并且可序列化的型型。調(diào)用者可以修改已賦值數(shù)組枚舉成員的訪問器返回的數(shù)組;這不會對其他調(diào)用者返回的數(shù)組產(chǎn)生任何影響全蝶。
方法摘要:
返回值 | 方法 |
---|---|
<T extends Annotation> T | getAnnotation(Class<T> annotationClass):如果存在該元素的指定類型的注釋闹蒜,則返回這些注釋,否則返回 null抑淫。 |
Annotation[] | getAnnotations():返回此元素上存在的所有注釋绷落。 |
Annotation[] | getDeclaredAnnotations():返回直接存在于此元素上的所有注釋。 |
boolean | sAnnotationPresent(Class<? extends Annotation> annotationClass):如果指定類型的注釋存在于此元素上始苇,則返回 true砌烁,否則返回 false。 |
所有已知實(shí)現(xiàn)類:AccessibleObject, Class, Constructor, Field, Method, Package
Class.isAnnotationPresent(Ann1.class):判斷該類上是否有Ann1注解存在
Field.isAnnotationPresent(Ann1.class):判斷該字段上是否有Ann1注解存在
Method.isAnnotationPresent(Ann1.class):判斷該方法上是否有Ann1注解存在
Servlet3.0注解新特性
Tomcat版本 | Servlet版本 | JavaEE版本 | JDK版本 |
---|---|---|---|
7.x | 3.0 | JavaEE6.0 | JDK6+ |
6.x | .5 | JavaEE5.0 | JDK5+ |
具體Servlet3.0注解使用及屬性查看@WebServlet注解即可。
注解的出現(xiàn)可以替換xml復(fù)雜的配置函喉,減輕代碼量避归,同時使用注解就等同于使用類硬編碼,但是它的優(yōu)點(diǎn)還是大于缺點(diǎn)管呵。
動態(tài)代理
Java的動態(tài)代理主要涉及到倆個類
- java.lang.reflect.Proxy
返回值 | 方法 |
---|---|
static InvocationHandler | getInvocationHandler(Object proxy) 返回指定代理實(shí)例的調(diào)用處理程序 |
static Class<?> | getProxyClass(ClassLoader loader, Class<?>... interfaces) 返回代理類的 java.lang.Class 對象梳毙,并向其提供類加載器和接口數(shù)組。 |
static boolean | static boolean isProxyClass(Class<?> cl) 當(dāng)且僅當(dāng)指定的類通過 getProxyClass 方法或 newProxyInstance 方法動態(tài)生成為代理類時捐下,返回 true账锹。 |
static Object | newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 返回一個指定接口的代理類實(shí)例,該接口可以將方法調(diào)用指派到指定的調(diào)用處理程序坷襟。 |
Proxy 提供用于創(chuàng)建動態(tài)代理類和實(shí)例的靜態(tài)方法奸柬,它還是由這些方法創(chuàng)建的所有動態(tài)代理類的超類
- java.lang.reflect.InvocationHandler
返回值 | 方法 |
---|---|
Object | invoke(Object proxy, Method method, Object[] args) 在代理實(shí)例上處理方法調(diào)用并返回結(jié)果。 |
使用:
創(chuàng)建某一接口 Foo 的代理:
InvocationHandler handler = new MyInvocationHandler(...);
Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), new Class[] { Foo.class });
Foo f = (Foo) proxyClass.getConstructor(new Class[] { InvocationHandler.class }).newInstance(new Object[] { handler });
或使用以下更簡單的方法:
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class[] { Foo.class }, handler);
總結(jié):動態(tài)代理對象的作用婴程,攔截業(yè)務(wù)邏輯進(jìn)行統(tǒng)一管理或控制廓奕,實(shí)現(xiàn)一種編程思想(AOP面向切面編程)
類加載器
- 類加載器的作用就是把存放在磁盤或網(wǎng)絡(luò)的.class文件加載到JVM虛擬機(jī)內(nèi)存中,并為之生成對應(yīng)的java.lang.Class對象
- JVM在啟動時會形成由三個類加載器組成的初始類加載器層次結(jié)構(gòu)档叔。
- 類加載器的父類委托機(jī)制
- BootStrap:爺爺
- ExtClassLoader:父親
- AppClassLoader:兒子
在加載一個.class文件的時候桌粉,執(zhí)行順序永遠(yuǎn)是:BootStrap-->ExtClassLoader-->AppClassLoader
子類永遠(yuǎn)委托父類去查找并加載,父類沒有范圍內(nèi)沒有找到對應(yīng)的.class文件則委托兒子尋找加載蹲蒲,若兒子依然沒有番甩,則拋出NotClassFoundException異常
支付
支付方式
WEB中的支付方式大致分為兩種:
- 分別接入各大銀行的支付API侵贵,優(yōu)點(diǎn)是:安全届搁、無額外的手續(xù)費(fèi)用等,直接與銀行進(jìn)行對接窍育;缺點(diǎn)是:開發(fā)工作量大卡睦,一旦銀行接口有變動就需要修改調(diào)整編碼
- 接入第三方支付服務(wù),第三方與銀行進(jìn)行對接漱抓,我們只需要集成第三方提供的API進(jìn)行引導(dǎo)用戶支付表锻。線下定期進(jìn)行資金結(jié)算即可。優(yōu)點(diǎn)是:快速乞娄,工作量兴惭贰;缺點(diǎn)是安全問題
支付流程
由圖可知仪或,Web支付确镊,其實(shí)所做的只有兩件事:按照第三方規(guī)范進(jìn)行數(shù)據(jù)組裝;驗(yàn)證三方返回數(shù)據(jù)范删,更改狀態(tài)蕾域。