锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
2:涓涓叿浣撳疄鐜?br />3:涓涓櫄鎷熸満瀹炰緥
java铏氭嫙鏈虹殑鐢熷懡鍛ㄦ湡
java铏氭嫙鏈虹殑澶╄亴灝辨槸:榪愯涓涓猨ava紼嬪簭.褰撲竴涓猨ava紼嬪簭榪愯寮濮嬭繍琛屾椂,涓涓櫄鎷熸満瀹炰緥灝變駭鐢熶簡.褰撲竴涓綆楁満涓婂悓鏃惰繍琛屼笁涓猨ava紼嬪簭.鍒欏皢浜х敓涓変釜java铏氭嫙鏈哄疄渚?姣忎釜紼嬪簭榪愯鍦ㄨ嚜宸辯殑铏氭嫙鏈洪噷闈?涓嶄細騫叉壈.褰撶▼搴忚繍琛屽畬姣曟椂,铏氭嫙鏈哄皢鑷姩閫鍑?
java铏氭嫙鏈洪噷闈㈡湁涓ょ綰跨▼,瀹堟姢綰跨▼鍜岄潪瀹堟姢綰跨▼.瀹堟姢綰跨▼鏄java铏氭嫙鏈鴻嚜宸辯殑綰跨▼,濡傚瀮鍦炬敹闆嗙嚎紼?鑰岄潪瀹堟姢綰跨▼鍒欐槸java涓繍琛岀殑紼嬪簭綰跨▼.褰撻潪瀹堟姢綰跨▼閮借繍琛屽畬浜?java铏氭嫙鏈哄皢閫鍑?
涓涓猨ava铏氭嫙鏈轟富瑕佸寘鎷簡:綾昏漿杞藉瓙緋葷粺,榪愯鏃舵暟鎹尯,鎵ц寮曟搸,鍐呭瓨鍖虹瓑絳?
榪愯鏃舵暟鎹尯------涓昏鏄?1 鍫?2聽 鏂規硶鍖?3 java鏍?br />
鍫嗗拰鏂規硶鍖哄铏氭嫙鏈哄疄渚嬩腑鎵鏈夌殑瀵硅薄閮芥槸鍏變韓鐨?鑰宩ava鏍堝尯,鏄姣忎釜綰跨▼閮芥槸鐙珛鐨? 褰撲竴涓猚lass琚澆鍏ュ埌 classloader涓椂,浼氳В鏋愬畠鐨勭被鍨嬩俊鎭?鎶婅繖浜涚被鍨嬩俊鎭斁鍒版柟娉曞尯,鑰屾妸紼嬪簭涓繍琛岀殑瀵硅薄,鏀懼埌鍫嗗尯.褰撲竴涓柊綰跨▼琚垱寤?灝卞垎閰嶄竴涓柊鐨刯ava鏍?java鏍堜腑淇濆瓨鐨?鏄柟娉曚腑鐨勪竴浜涘彉閲?鐘舵?java鏍堟槸鐢卞緢澶氱殑java鏍堝撫緇勬垚鐨?涓涓爤甯у寘鍚簡涓涓柟娉曡繍琛岀殑鐘舵?褰撲竴涓柟娉曡鎵ц鐨勬椂鍊?灝卞帇鍏ヤ竴涓柊鐨刯ava鏍堝撫鍒癹ava鏍堜腑,鏂規硶榪斿洖鐨勬椂鍊?灝辨妸鏍堝撫寮瑰嚭鏉?鎶涘純鎺?
鏂規硶鍖?br />
鍦╦ava铏氭嫙鏈轟腑,琚杞界殑綾葷殑綾誨瀷淇℃伅鍜岀被鐨勯潤鎬佸彉閲忚瀛樺偍鍦ㄦ柟娉曞尯榪欐牱鐨勫唴瀛橀噷闈?java紼嬪簭榪愯鏃?浼氭煡鎵捐繖浜涗釜淇℃伅.鏂規硶鍖虹殑澶у皬,鏄姩鎬佺殑.涔熷彲浠ヤ笉鏄繛緇殑.鍙嚜鐢卞湪鍫嗕腑鍒嗛厤.涔熷彲浠ョ敱鐢ㄦ埛鎴栬呯▼搴忓憳鎸囧畾.鏂規硶鍖哄彲琚瀮鍦炬敹闆?
鏂規硶鍖哄彲浠ヤ繚瀛樹互涓嬩俊鎭?br />榪欎釜綾誨瀷鐨勫叏闄愬畾鍚?br />鐩存帴瓚呯被鐨勫叏闄愬畾鍚?br />鏄被綾誨瀷榪樻槸鎺ュ彛
綾誨瀷鐨勮闂慨楗扮
浠諱綍鐩存帴瓚呯被鎺ュ彛鐨勫叏闄愬畾鍚嶇殑鏈夊簭鍒楄〃.
璇ョ被鍨嬬殑甯擱噺姹?br />瀛楁淇℃伅 綾諱腑澹版槑鐨勬瘡涓瓧孌靛強鍏墮『搴?濡傚瓧孌靛悕,綾誨瀷.淇グ絎﹀彿.
鏂規硶淇℃伅:濡傛柟娉曞悕,榪斿洖綾誨瀷.鍙傛暟琛ㄥ垪.淇グ絎﹀彿.瀛楄妭鐮?鎿嶄綔鏁版爤鍜屾爤甯т腑灞閮ㄥ彉閲忓尯澶у皬絳夌瓑
綾婚潤鎬佸彉閲?br />涓涓埌綾籧lassloader鐨勫紩鐢?br />涓涓埌class綾葷殑寮曠敤
鍫?br />鐢ㄦ潵瀛樺偍榪愯鏃剁殑瀵硅薄瀹炰緥
java鏍?br />姣忓惎鍔ㄤ竴涓柊鐨勭嚎紼?灝變細鍒嗛厤鍒頒竴涓猨ava鏍?java鏍堜互甯т負鍗曚綅淇濆瓨綰跨▼鐨勮繍琛岀姸鎬?瀹冩湁涓ょ鎿嶄綔.鍏ユ爤,鍑烘爤.
褰撲竴涓柟娉曡璋冪敤鏃?鍏ユ爤,褰撲竴涓柟娉曡繑鍥炴椂,鍑烘爤,鎴栬呭綋鏂規硶鍑虹幇寮傚父.涔熷嚭鏍?
鏍堝撫
緇勬垚閮ㄥ垎 灞閮ㄥ彉閲忓尯,鎿嶄綔鏁版爤,甯ф暟鎹尯.
]]>
java涓篃瑕佹敞鎰忓唴瀛樼鐞?br />
// Can you spot the "memory leak"?
public class Stack {
private Object[] elements;
private int size = 0;
public Stack(int initialCapacity) {
this.elements = new Object[initialCapacity];
}
Effective Java: Programming Language Guide
17
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0)
throw new EmptyStackException();
return elements[--size];
}
/**
* Ensure space for at least one more element, roughly
* doubling the capacity each time the array needs to grow.
*/
private void ensureCapacity() {
if (elements.length == size) {
Object[] oldElements = elements;
elements = new Object[2 * elements.length + 1];
System.arraycopy(oldElements, 0, elements, 0, size);
}
}
}
榪欓噷鏈変竴涓唴瀛樻硠婕?br />濡傛灉涓涓爤鍏堟槸澧為暱錛岀劧鍚庡啀鏀剁緝錛岄偅涔堬紝浠庢爤涓脊鍑烘潵鐨勫璞″皢涓嶄細琚綋鍋氬瀮鍦懼洖鏀訛紝鍗充嬌浣跨敤鏍堢殑瀹㈡埛紼嬪簭涓嶅啀寮曠敤榪欎簺瀵硅薄錛屽畠浠篃涓嶄細琚洖鏀躲傝繖鏄洜涓猴紝鏍堝唴閮ㄧ淮鎶ょ潃瀵硅繖浜涘璞$殑榪囨湡寮曠敤錛坥bsolete re f e re n c e錛夈傛墍璋撹繃鏈熷紩鐢紝鏄寚姘歌繙涔熶笉浼氬啀琚В闄ょ殑寮曠敤
鏀規
public Object pop() {
if (size==0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // Eliminate obsolete reference娓呴櫎寮曠敤
return result;
}
褰撶▼搴忓憳絎竴嬈¤綾諱技榪欐牱鐨勯棶棰樺洶鎵扮殑鏃跺欙紝浠栦滑寰寰浼氳繃鍒嗗皬蹇冿細瀵逛簬姣忎竴涓璞″紩鐢紝涓鏃︾▼搴忎笉鍐嶇敤鍒板畠錛屽氨鎶婂畠娓呯┖銆傝繖鏍峰仛鏃㈡病蹇呰錛屼篃涓嶆槸鎴戜滑鎵鏈熸湜鐨勶紝鍥犱負榪欐牱鍋氫細鎶婄▼搴忎唬鐮佸紕寰楀緢涔憋紝騫朵笖鍙互鎯沖儚榪樹細闄嶄綆紼嬪簭鐨勬ц兘銆傗滄竻絀哄璞″紩鐢ㄢ濊繖鏍風殑鎿嶄綔搴旇鏄竴縐嶄緥澶栵紝鑰屼笉鏄竴縐嶈鑼冭涓恒傛秷闄よ繃鏈熷紩鐢ㄦ渶濂界殑鏂規硶鏄噸鐢ㄤ竴涓湰鏉ュ凡緇忓寘鍚璞″紩鐢ㄧ殑鍙橀噺錛屾垨鑰呰榪欎釜鍙橀噺緇撴潫鍏剁敓鍛藉懆鏈熴傚鏋滀綘鏄湪鏈绱у噾鐨勪綔鐢ㄥ煙鑼冨洿鍐呭畾涔夋瘡涓涓彉閲忥紙瑙佺2 9鏉★級錛屽垯榪欑鎯呭艦灝變細鑷劧鑰岀劧鍦板彂鐢熴傚簲璇ユ敞鎰忓埌錛屽湪鐩墠鐨凧 V M瀹炵幇騫沖彴涓婏紝浠呬粎閫鍑哄畾涔夊彉閲忕殑浠g爜鍧楁槸涓嶅鐨勶紝瑕佹兂浣垮紩鐢ㄦ秷澶憋紝蹇呴』閫鍑哄寘鍚鍙橀噺鐨勬柟娉曘?br />
涓鑸岃█錛屽彧瑕佷竴涓被鑷繁綆$悊瀹冪殑鍐呭瓨錛岀▼搴忓憳灝卞簲璇ヨ鎯曞唴瀛樻硠婕忛棶棰樸備竴鏃︿竴涓厓绱犺閲婃斁鎺夛紝鍒欒鍏冪礌涓寘鍚殑浠諱綍瀵硅薄寮曠敤搴旇瑕佽娓呯┖銆?br />
鍐呭瓨娉勬紡鐨勫彟涓涓父瑙佹潵婧愭槸緙撳瓨銆備竴鏃︿綘鎶婁竴涓璞″紩鐢ㄦ斁鍒頒竴涓紦瀛樹腑錛屽畠灝卞緢瀹規槗琚仐蹇樻帀錛屼粠鑰屼嬌寰楀畠涓嶅啀鏈夌敤涔嬪悗寰堥暱涓孌墊椂闂村唴浠嶇劧鐣欏湪緙撳瓨涓?br />
]]>
String s = new String("silly"); // DON'T DO THIS!
String s = "No longer silly";//do this
In addition to reusing immutable objects, you can also reuse mutable objects that you know will not be modified. Here is a slightly more subtle and much more common example of what not to do, involving mutable objects that are never modified once their values have been computed:
闄や簡閲嶇敤闈炲彲鍙樼殑瀵硅薄涔嬪錛屽浜庨偅浜涘凡鐭ヤ笉浼氳淇敼鐨勫彲鍙樺璞★紝浣犱篃鍙互閲嶇敤瀹冧滑銆?br />
such as
public class Person {
private final Date birthDate;
// Other fields omitted
public Person(Date birthDate) {
this.birthDate = birthDate;
}
// DON'T DO THIS!
public boolean isBabyBoomer() {
Calendar gmtCal =
Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
Date boomStart = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
Date boomEnd = gmtCal.getTime();
return birthDate.compareTo(boomStart) >= 0 &&
birthDate.compareTo(boomEnd) < 0;
}
}
鏀硅壇鐨勭増鏈?
The isBabyBoomer method unnecessarily creates a new Calendar, TimeZone, and two Date instances each time it is invoked. The version that follows avoids this inefficiency with a static initializer:
class Person {
private final Date birthDate;
public Person(Date birthDate) {
this.birthDate = birthDate;
}
/**
* The starting and ending dates of the baby boom.
*/
private static final Date BOOM_START;
private static final Date BOOM_END;
static {
Calendar gmtCal =
Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_START = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END = gmtCal.getTime();
}
public boolean isBabyBoomer() {
return birthDate.compareTo(BOOM_START) >= 0 &&
birthDate.compareTo(BOOM_END) < 0;
}
}
銆備竴涓傞厤鍣ㄦ槸鎸囪繖鏍蜂竴涓璞★細瀹冩妸鍔熻兘濮?br />鎵樼粰鍚庨潰鐨勪竴涓璞★紝浠庤屼負鍚庨潰鐨勫璞℃彁渚涗竴涓彲閫夌殑鎺ュ彛銆傜敱浜庨傞厤鍣ㄩ櫎浜嗗悗闈㈢殑瀵硅薄涔嬪錛屾病鏈夊叾浠栫殑鐘舵佷俊鎭紝鎵浠ラ拡瀵規煇涓粰瀹氬璞$殑鐗瑰畾閫傞厤鍣ㄨ岃█錛屽畠涓嶉渶瑕佸垱寤哄涓傞厤鍣ㄥ疄渚嬨?br />
This item should not be misconstrued to imply that object creation is expensive and should be avoided. On the contrary, the creation and reclamation of small objects whose constructors do little explicit work is cheap, especially on modern JVM implementations. Creating additional objects to enhance the clarity, simplicity, or power of a program is generally a good thing.
Conversely, avoiding object creation by maintaining your own object pool is a bad idea unless the objects in the pool are extremely heavyweight. A prototypical example of an object that does justify an object pool is a database connection. The cost of establishing the connection is sufficiently high that it makes sense to reuse these objects. Generally speaking, however, maintaining your own object pools clutters up your code, increases memory footprint, and harms performance. Modern JVM implementations have highly optimized garbage collectors that easily outperform such object pools on lightweight objects.
]]>
Occasionally you'll want to write a class that is just a grouping of static methods and static fields.鏈夋椂鍊?浣犳兂鍐欎竴涓被,鍙槸闇瑕佷粬鎻愪緵浜嗕竴緋誨垪鐨勫嚱鏁版搷浣滅瓑,鑰屼笉鎯寵瀹冨疄渚嬪寲.濡?java.lang.Math or java.util.Arrays.
浣嗘槸濡傛灉浣犱笉鎻愪緵鏋勯犲嚱鏁?緙栬瘧鍣ㄤ細鑷姩娣誨姞涓涓?
鎵浠ュ繀欏繪彁渚涗竴涓?姝ゆ椂,鎶婃瀯閫犲嚱鏁拌緗負private.灝卞彲浠ヨ揪鍒扮洰鐨?
涓鑸敤涓庡伐鍏風被.
// Noninstantiable utility class
public class UtilityClass {
// Suppress default constructor for noninstantiability
private UtilityClass() {
// This constructor will never be invoked
}
... // Remainder omitted
}
鐢變簬private鐨勬瀯鍜卞嚱鏁?璇ョ被涓嶈兘琚疄渚嬪寲.鍚屾椂.涓嶈兘琚戶鎵夸簡.
]]>
A singleton is simply a class that is instantiated exactly once [Gamma98, p. 127].濡傛暟鎹簱璧勬簮絳?
There are two approaches to implementing singletons. Both are based on keeping the
constructor private and providing a public static member to allow clients access to the sole
instance of the class. In one approach, the public static member is a final field:
// Singleton with final field
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() {
...
}
... // Remainder omitted
}
1:鏋勯犲嚱鏁扮鏈?br />2:鎻愪緵涓涓潤鎬乻tatic鐨刦inal鎴愬憳
The private constructor is called only once, to initialize the public static final field
Elvis.INSTANCE.聽
Exactly one Elvis instance will exist once the Elvis class is initialized鈥攏o more,
no less. Nothing that a client does can change this.
In a second approach, a public static factory method is provided instead of the public static final field:
// Singleton with static factory
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() {
...
}
public static Elvis getInstance() {
return INSTANCE;
}
... // Remainder omitted
}
鐢ㄩ潤鎬佹柟娉曡繑鍥?鑰屼笉鏄洿鎺ヨ繑鍥炰竴涓疄渚?
濡傛灉瀵瑰璞″簭鍒楀寲,瑕佸仛澶氫竴鐐瑰伐浣?濡?br />To make a singleton class serializable (Chapter 10), it is not sufficient merely to add
implements Serializable to its declaration. To maintain the singleton guarantee, you must
also provide a readResolve method (Item 57). Otherwise, each deserialization of a serialized instance will result in the creation of a new instance, 鍚﹀垯,緇忚繃瀵硅薄鍙嶅簭鍒楀寲鍚?浼氬鑷村垱寤轟簡涓涓柊鐨勫璞?leading, in the case of our example, to spurious Elvis sightings. To prevent this, add the following readResolve method to the Elvis class:
// readResolve method to preserve singleton property
private Object readResolve() throws ObjectStreamException {
/*
* Return the one true Elvis and let the garbage collector
* take care of the Elvis impersonator.
*/
return INSTANCE;
}
]]>
constructors 鑰冭檻浠ラ潤鎬佸伐鍘傛柟娉曞彇浠f瀯閫犲嚱鏁?br />
The normal way for a class to allow a client to obtain an instance is to provide a public
constructor.
A class can provide a public static factory method, which is simply
a static method that returns an instance of the class
such as
public static Boolean valueOf(boolean b) {
return (b ? Boolean.TRUE : Boolean.FALSE);
}
advantages
1:One advantage of static factory methods is that, unlike constructors, they have names.
涓涓被闈欐佸伐鍘傛柟娉曟槸鏈夊悕瀛楃殑.If the parameters to a constructor do not, in and of themselves, describe the object being returned, a static factory with a well-chosen name can make a class easier to use and the resulting client code easier to read. 濡侭igInteger(int, int,Random)鍙煡閬搉ew浜嗕竴涓狟igInteger瀵硅薄,鑰孊igInteger.probablePrime()鑳借鏄庤繑鍥炵殑鍙兘鏄竴涓礌鏁板璞?鍙﹀,濡傛灉涓涓瀯閫犲嚱鏁頒粎浠呯敱浜庡弬鏁伴『搴忎笉鍚岃屾剰鎬濅篃涓嶅悓.闈欐佸伐鍘傛柟娉曞氨鏇村姞鏈夌敤浜?瀹冩洿鑳借鏄庡嚱鏁扮殑鎰忔?鍥犱負瀹冩湁涓涓悕瀛?
the reason聽are : If the parameters to a constructor do not, describe the object being
returned, a static factory with a well-chosen name can make a class easier to use and the
resulting client code easier to read.
2:A second advantage of static factory methods is that, unlike constructors, they are not
required to create a new object each time they're invoked.姣忔璇鋒眰鏃?涓嶉渶瑕侀噸鏂板垱寤轟竴涓璞?---鍗曚緥鐨勬剰鎬?榪欏彲浠ュ湪浠諱綍鏃跺埢鎺у埗榪欎釜瀵硅薄,鍚屾椂鍦ㄦ瘮杈冪殑鏃跺欎篃涓嶉渶瑕佺敤equals鑰岀敤= =灝卞彲浠ヨВ鍐充簡.
3:A third advantage of static factory methods is that, unlike constructors, they can return
an object of any subtype of their return type.鍙互榪斿洖涓涓師榪斿洖綾誨瀷鐨勫瓙綾誨瀷瀵硅薄.
One application of this flexibility is that an API can return objects without making their
classes public.Hiding implementation classes in this fashion can lead to a very compact API.榪欑鐏墊椿鎬х殑涓涓簲鐢ㄦ槸錛屼竴涓狝 P I鍙互榪斿洖涓涓璞★紝鍚屾椂鍙堜笉浣胯瀵硅薄鐨勭被鎴愪負鍏湁鐨勩備互榪欑鏂瑰紡鎶婂叿浣撶殑瀹炵幇綾婚殣钘忚搗鏉ワ紝鍙互寰楀埌涓涓潪甯哥畝媧佺殑A P I銆傝繖欏規妧鏈潪甯擱傚悎
浜庡熀浜庢帴鍙g殑妗嗘灦緇撴瀯錛屽洜涓哄湪榪欐牱鐨勬鏋剁粨鏋勪腑錛屾帴鍙f垚涓洪潤鎬佸伐鍘傛柟娉曠殑鑷劧榪斿洖綾誨瀷
sample:
// Provider framework sketch
public abstract class Foo {
// Maps String key to corresponding Class object
private static Map implementations = null;
// Initializes implementations map the first time it's called
private static synchronized void initMapIfNecessary() {
if (implementations == null) {
implementations = new HashMap();
// Load implementation class names and keys from
// Properties file, translate names into Class
// objects using Class.forName and store mappings.
...
}
}
public static Foo getInstance(String key) {
initMapIfNecessary();
Class c = (Class) implementations.get(key);
if (c == null)
return new DefaultFoo();
try {
return (Foo) c.newInstance();
} catch (Exception e) {
return new DefaultFoo();
}
}
}
鍏湁鐨勯潤鎬佸伐鍘傛柟娉曟墍榪斿洖鐨勫璞$殑綾諱笉浠呭彲浠ユ槸闈炲叕鏈夌殑錛岃屼笖璇ョ被鍙互闅忕潃姣忔璋冪敤
鑰屽彂鐢熷彉鍖栵紝榪欏彇鍐充簬闈欐佸伐鍘傛柟娉曠殑鍙傛暟鍊箋傚彧瑕佹槸宸插0鏄庣殑榪斿洖綾誨瀷鐨勫瓙綾誨瀷錛岄兘鏄厑
璁哥殑銆傝屼笖錛屼負浜嗗寮鴻蔣浠剁殑鍙淮鎶ゆэ紝榪斿洖瀵硅薄鐨勭被涔熷彲浠ラ殢鐫涓嶅悓鐨勫彂琛岀増鏈屼笉鍚屻?br />disadvantages:
1:The main disadvantage of static factory methods is that classes without public or protected constructors cannot be subclassed.
綾誨鏋滀笉鍚叕鏈夌殑鎴栬呭彈淇濇姢鐨勬瀯閫犲嚱鏁幫紝灝變笉鑳借瀛愮被鍖栥傚浜庡叕鏈夌殑闈欐佸伐鍘傛墍榪斿洖鐨勯潪鍏湁綾伙紝涔熷悓鏍峰姝?br />
2:A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods.
In summary, static factory methods and public constructors both have their uses, and it pays to understand their relative merits. Avoid the reflex to provide constructors without first considering static factories because static factories are often more appropriate. If you've weighed the two options and nothing pushes you strongly in either direction, it's probably best to provide a constructor simply because it's the norm.
public interface HelloI {
聽public String sayHello(String firstName,String lastName)throws Exception;
聽}
綾諱慨鏀逛負
package net.blogjava.dodoma.spring.aop;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Hello implements HelloI {
聽protected static final Log log=LogFactory.getLog(Hello.class);
聽private String msg;
聽public Hello(){}
聽public Hello(String msg){
聽聽this.msg=msg;
聽}
聽
聽public String getMsg() {
聽聽return msg;
聽}
聽public void setMsg(String msg) {
聽聽this.msg = msg;
聽}
聽public String sayHello(String firstName, String lastName) throws Exception{
聽聽// TODO Auto-generated method stub
聽聽log.info("in the class "+this.getClass().getName()+"'s method sayHello()");
聽 throw new Exception("here is a exception !");
聽聽return (msg+" "+firstName+" "+lastName);
聽}
}
package net.blogjava.dodoma.spring.aop;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.ThrowsAdvice;
public class LogThrowAdvice implements ThrowsAdvice {
聽protected static final Log log = LogFactory.getLog(LogThrowAdvice.class);
聽public void afterThrowing(Exception e)throws Throwable{
聽聽log.info("in the class "+this.getClass().getName()+"'s method afterThrowing()");
聽聽log.info("the exception is "+e.getMessage());
聽}
}
package net.blogjava.dodoma.spring.aop;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class HelloTest {
聽protected static final Log log = LogFactory.getLog(HelloTest.class);
聽/**
聽 * @param args
聽 * @throws Exception
聽 */
聽public static void main(String[] args) throws Exception {
聽聽// TODO Auto-generated method stub
聽聽Resource rs = new ClassPathResource("beans.xml");
聽聽BeanFactory bf = new XmlBeanFactory(rs);
聽聽HelloI h = (HelloI) bf.getBean("theBean");
聽聽log.info("starting...");
聽聽try {
聽聽聽log.info(h.sayHello("ma", "bin"));
聽聽} catch (Exception e) {
聽聽聽e.printStackTrace();
聽聽}
聽聽log.info("end...");
聽聽
聽聽
聽聽ProxyFactory factory=new ProxyFactory();
聽聽factory.addAdvice(new LogThrowAdvice ());
聽聽factory.setTarget(new Hello("hello"));
聽聽try{
聽聽HelloI hi=(HelloI)factory.getProxy();
聽聽hi.sayHello("ma","bin");}
聽聽catch(Exception e){e.printStackTrace();}
聽}
}
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class LogAroundAdvice implements MethodInterceptor {
聽protected static final Log log = LogFactory.getLog(LogAroundAdvice.class);
聽public Object invoke(MethodInvocation arg) throws Throwable {
聽聽//聽璋冪敤鐩爣瀵硅薄涔嬪墠
聽聽log.info("before the target object");
聽聽Object val=arg.proceed();
聽 //璋冪敤鐩爣瀵硅薄涔嬪悗
聽聽log.info("the arg is "+arg);
聽聽log.info("after the target object");
聽聽return val;
聽}
}
嫻嬭瘯鏂規硶
package net.blogjava.dodoma.spring.aop;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class HelloTest {
聽protected static final Log log = LogFactory.getLog(HelloTest.class);
聽/**
聽 * @param args
聽 * @throws Exception
聽 */
聽public static void main(String[] args) throws Exception {
聽聽// TODO Auto-generated method stub
聽聽Resource rs = new ClassPathResource("beans.xml");
聽聽BeanFactory bf = new XmlBeanFactory(rs);
聽聽HelloI h = (HelloI) bf.getBean("theBean");
聽聽log.info("starting...");
聽聽try {
聽聽聽log.info(h.sayHello("ma", "bin"));
聽聽} catch (Exception e) {
聽聽聽e.printStackTrace();
聽聽}
聽聽log.info("end...");
聽聽
聽聽
聽聽ProxyFactory factory=new ProxyFactory();
聽聽factory.addAdvice(new LogAroundAdvice ());
聽聽factory.setTarget(new Hello("hello"));
聽聽try{
聽聽HelloI hi=(HelloI)factory.getProxy();
聽聽hi.sayHello("ma","bin");}
聽聽catch(Exception e){e.printStackTrace();}
聽}
}
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.AfterReturningAdvice;
public class LogAfterAdvice implements AfterReturningAdvice {
聽protected static final Log log = LogFactory.getLog(LogAfterAdvice.class);
聽public void afterReturning(Object returnVal, Method m, Object[] args,
聽聽聽Object target) throws Throwable {
聽聽// TODO Auto-generated method stub
聽聽log.info("in the class "+this.getClass().getName()+"'s method afterReturning()");
聽聽log.info("the target class is:" + target.getClass().getName());
聽聽log.info("the target method is:" + m.getName());
聽聽for (int i = 0; i < args.length; i++) {
聽聽聽log.info("the method's args is:" + args[i]);
聽聽}
聽聽
聽聽log.info("the returnValue is "+returnVal);
聽聽//嫻嬭瘯,濡傛灉榪斿洖瑁呭鍙戠敓浜嗗紓甯?灝嗗浣曞鐞嗙▼搴忔祦紼?br />聽聽//throw new Exception("榪斿洖瑁呭鍙戠敓寮傚父");
聽}
}
嫻嬭瘯浠g爜
package net.blogjava.dodoma.spring.aop;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class HelloTest {
聽protected static final Log log = LogFactory.getLog(HelloTest.class);
聽/**
聽 * @param args
聽 * @throws Exception
聽 */
聽public static void main(String[] args) throws Exception {
聽聽// TODO Auto-generated method stub
聽聽Resource rs = new ClassPathResource("beans.xml");
聽聽BeanFactory bf = new XmlBeanFactory(rs);
聽聽HelloI h = (HelloI) bf.getBean("theBean");
聽聽log.info("starting...");
聽聽try {
聽聽聽log.info(h.sayHello("ma", "bin"));
聽聽} catch (Exception e) {
聽聽聽e.printStackTrace();
聽聽}
聽聽log.info("end...");
聽聽
聽聽
聽聽ProxyFactory factory=new ProxyFactory();
聽聽factory.addAdvice(new LogAfterAdvice());
聽聽factory.setTarget(new Hello("hello"));
聽聽try{
聽聽HelloI hi=(HelloI)factory.getProxy();
聽聽hi.sayHello("ma","bin");}
聽聽catch(Exception e){e.printStackTrace();}
聽}
}
鍦╞eans.xml涓姞鍏ュ涓嬩唬鐮?br /><bean id="theLogAfterAdvice" class="net.blogjava.dodoma.spring.aop.LogAfterAdvice"/>
<property name="interceptorNames">
聽聽聽聽聽 <list>
聽聽聽聽聽聽聽 <value>theLogAfterAdvice</value><!--姝ゆ椂鐩存帴浣跨敤advice,琛ㄦ槑榪欎釜綾繪墍鏈夌殑瀹炰緥,鏂規硶,閮戒韓鍙梐dvice鐨勬嫤鎴?->
聽聽聽聽聽聽 </list>聽
</property>
鍒囧叆鐐瑰彲鐪佺暐,濡傞渶瑕佺殑璇?br />濡?br />
<!--鍒囧叆鐐?->
聽 <!--Note: An advisor assembles pointcut and advice-->
聽 <bean id="theBeAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
聽聽聽 <property name="advice">
聽聽聽聽聽 <ref local="theLogAfterAdvice"/>
聽聽聽 </property>
聽聽聽 <!--鍖歸厤妯″紡-->
聽聽聽 <property name="pattern">
聽聽聽聽聽 <value>.*</value>
聽聽聽 </property>
聽 </bean>
public interface HelloI {
聽public String sayHello(String firstName,String lastName);
聽}
瀹炵幇綾?br />package net.blogjava.dodoma.spring.aop;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Hello implements HelloI {
聽protected static final Log log=LogFactory.getLog(Hello.class);
聽private String msg;
聽public Hello(){}
聽public Hello(String msg){
聽聽this.msg=msg;
聽}
聽public String getMsg() {
聽聽return msg;
聽}
聽public void setMsg(String msg) {
聽聽this.msg = msg;
聽}
聽public String sayHello(String firstName, String lastName) {
聽聽// TODO Auto-generated method stub
聽聽log.info("in the class "+this.getClass().getName()+"'s method sayHello()");
聽聽return (msg+" "+firstName+" "+lastName);
聽}
}
BeforeAdvice閫氱煡
package net.blogjava.dodoma.spring.aop;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.MethodBeforeAdvice;
/**
聽* 鏂規硶璋冪敤涔嬪墠.
聽* 鍏堣皟鐢ㄦ鏂規硶
聽* @author dodoma
聽**/
public class LogBeforeAdvice implements MethodBeforeAdvice {
聽protected static final Log log = LogFactory.getLog(LogBeforeAdvice.class);
聽public void before(Method m, Object[] args, Object target) throws Throwable {
聽聽log.info("in the class "+this.getClass().getName()+"'s method before()");
聽聽log.info("the target class is:" + target.getClass().getName());
聽聽log.info("the target method is:" + m.getName());
聽聽for (int i = 0; i < args.length; i++) {
聽聽聽log.info("the method's args is:" + args[i]);
聽聽}
聽聽//嫻嬭瘯,濡傛灉鍦╞efore閫氱煡涓彂鐢熶簡寮傚父,紼嬪簭嫻佺▼灝嗗浣?br />聽聽//throw new Exception("寮傚父");
聽}
}
嫻嬭瘯綾?br />package net.blogjava.dodoma.spring.aop;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class HelloTest {
聽protected static final Log log = LogFactory.getLog(HelloTest.class);
聽public static void main(String[] args) throws Exception {
聽聽// TODO Auto-generated method stub
聽//搴旂敤spring鐨刬oc瀹瑰櫒
聽聽Resource rs = new ClassPathResource("beans.xml");
聽聽BeanFactory bf = new XmlBeanFactory(rs);
聽聽HelloI h = (HelloI) bf.getBean("theBean");
聽聽log.info("starting...");
聽聽try {
聽聽聽log.info(h.sayHello("ma", "bin"));
聽聽聽聽聽} catch (Exception e) {
聽聽聽e.printStackTrace();
聽聽}
聽聽log.info("end...");
聽聽
聽聽//濡傛灉娌℃湁浣跨敤spring鐨刬oc,鍙互鐩存帴鐢ㄥ涓嬩唬鐮佹祴璇?br />聽聽ProxyFactory factory=new ProxyFactory();
聽聽factory.addAdvice(new LogBeforeAdvice());//娣誨姞閫氱煡
聽聽factory.setTarget(new Hello("hello"));//娣誨姞琚唬鐞嗙殑綾誨疄渚?br />聽聽try{
聽聽HelloI hi=(HelloI)factory.getProxy();
聽聽hi.sayHello("ma","bin");}
聽聽catch(Exception e){e.printStackTrace();}
聽}
}