【正文】
p this interceptor and invoke the next in the chain. return proceed()。 }public Object proceed() throws Throwable { // We start with an index of 1 and increment early. if ( == () 1) { return invokeJoinpoint()。 7. Spring AOP兩種實現(xiàn)機制 (Baoming Chai)SPRING是通過動態(tài)代理來實現(xiàn)AOP的,SPRING內(nèi)部提供了2種實現(xiàn)機制 , public Object getProxy(ClassLoader classLoader) { if (()) { Class targetClass = ().getTargetClass()。通過策略接口,MVC 框架變成為高度可配置的,MVC 容納了大量視圖技術(shù),其中包括 JSP、Velocity、Tiles、iText 和 POI。所以,Spring 框架支持與 Jakarta Struts 的集成。 Spring ORM:Spring 框架插入了若干個 ORM 框架,從而提供了 ORM 的對象關(guān)系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。 Spring DAO:JDBC DAO 抽象層提供了有意義的異常層次結(jié)構(gòu),可用該結(jié)構(gòu)來管理異常處理和不同數(shù)據(jù)庫供應(yīng)商拋出的錯誤消息。所以,可以很容易地使 Spring 框架管理的任何對象支持 AOP。 Spring 上下文:Spring 上下文是一個配置文件,向 Spring 框架提供上下文信息。 核心容器:核心容器提供 Spring 框架的基本功能。6. Spring框架 (Minjin)Spring 框架是一個分層架構(gòu),由 7 個定義良好的模塊組成。 (Double J)。 } catch (Exception e) { ()。 //反射執(zhí)行start方法 (, new Object[] { method })。 return ( ().getClassLoader(), .getClass().getInterfaces(), this)。 4. 6 5. 7 public class DynaProxyHello implements InvocationHandler { 6. 8 private Object proxy。} LoggerOperation())。Hello(),newhellomain(String[]{}}catchObject[] Class[]end result })。new })。newstart ()。//反射得到操作者的實例 null。Methodpublic.getClass().getInterfaces(), ().getClassLoader(), delegate。 proxy。 proxy)publicObject proxy。DynaProxyHello下面是轉(zhuǎn)載的一個簡單示例。所謂的控制反轉(zhuǎn),作為中文更好理解的一個翻譯應(yīng)該是依賴注入,把依賴的類采用接口的方式,利用Set函數(shù),傳入Bean的內(nèi)部,實現(xiàn)與外界的解耦合。 首先,IoC,控制反轉(zhuǎn)。我們看看Spring是怎么做的。Gc.5. Spring IOC and AOP(Minjin)IoC和AOP都是Spring的核心思想 gc”,老生代的GC命名為FullJVM的垃圾收集策略 Collector(標(biāo)記整理收集器) 標(biāo)記整理收集器汲取了標(biāo)記清除和復(fù)制收集器的優(yōu)點,它分兩個階段執(zhí)行,在第一個階段,首先掃描所有活躍的對象,并標(biāo)記所有活躍的對象,第二個階段首先清除未標(biāo)記的對象,然后將活躍的的對象復(fù)制到堆得底部。CopyingCollector(標(biāo)記清除收集器) 標(biāo)記清除收集器最早由Lisp的發(fā)明人于1960年提出,標(biāo)記清除收集器停止所有的工作,從根掃描每個活躍的對象,然后標(biāo)記掃描過的對象,標(biāo)記完成以后,清除那些沒有被標(biāo)記的對象。PhantomassertNull(())。newtest。reference弱引用有利于對象更快的被回收,假如一個對象沒有強引用只有弱引用,那么在GC后,這個對象肯定會被回收。}SoftReferenceString(str)。SoftReferenceStringstrPublic216。null。=newvoidReferencereference,Phantomgc的時候就會只掃描被標(biāo)記為臟狀態(tài)的卡片,而不需要掃描整個堆。gc只需要掃描新生代,而不需要掃描老生代。引用計數(shù)是最簡單直接的一種方式,這種方式在每一個對象中增加一個引用的計數(shù),這個計數(shù)代表當(dāng)前程序有多少個引用引用了此對象,如果此對象的引用計數(shù)變?yōu)?,那么此對象就可以作為垃圾收集器的目標(biāo)對象來收集。 通常大家還會遇到另外一種內(nèi)存溢出錯誤“永久存儲區(qū)溢出(: Java Permanent Space)”。 如果幸存者1區(qū)有足夠控件存放則直接放到幸存者1區(qū);如果幸存者0區(qū)沒有足夠空間存放,則JVM的垃圾回收器執(zhí)行對幸存者0區(qū)的垃圾回收工作,銷毀那些不再被其他對象引用的JAVA對象(如果該對象僅僅被一個沒有其他對象引用的對象引用的話,此對象也被歸為沒有存在的必要,依此類推),并將那些被其他對象所引用的JAVA對象移動到養(yǎng)老區(qū)。首先當(dāng)啟動J2EE應(yīng)用服務(wù)器時,JVM隨之啟動,并將JDK的類和接口,應(yīng)用服務(wù)器運行時需要的類和接口以及J2EE應(yīng)用的類和接口定義文件也及編譯后的Class文件或JAR包中的Class文件裝載到JVM的永久存儲區(qū)。當(dāng)將伊甸園中的還有其他對象引用的對象移動到幸存者0區(qū)時,如果幸存者0區(qū)也沒有空間來存放這些對象時,JVM的垃圾回收器將對幸存者0區(qū)進行垃圾回收處理,將幸存者0區(qū)中不在有其他對象引用的JAVA對象進行銷毀,將幸存者0區(qū)中還有其他對象引用的對象移動到幸存者1區(qū)。創(chuàng)建對象的依據(jù)即是永久存儲區(qū)中的元數(shù)據(jù)。堆空間又分別按JAVA對象的創(chuàng)建和年齡特征分為養(yǎng)老區(qū)和新生區(qū)。具體分區(qū)如下圖: 那JVM他的這些分區(qū)各有什么用途,請看下面的解說。持久代大小通過XX:MaxPermSize=進行設(shè)置。 2. Tenured(年老代)JVM specification中的 Heap的一部份 年老代存放從年輕代存活的對象。大部分對象在Eden區(qū)中生成?,F(xiàn)在的垃圾回收器()都是使用此算法的。 } else { (They are different instances)。 // Result: They are same instances String B1 = new String(A)。public static void main(String[] args) { String A1 = A。如果一個類是不變類,這個類是不是就不能有改變狀態(tài)的方法呢?答案當(dāng)然是否定的,String是一個不變類,仍然有replace,replaceAll這樣的方法,而String仍然是一個不變類,那是因為在這些改變狀態(tài)的方法中,每次都是新創(chuàng)建一個String對象。 // Default to 0 public int hashCode() {int h = hash。// 這個方法不會創(chuàng)建新的對象,而是重用已經(jīng)創(chuàng)建好的instance public static Boolean valueOf(boolean b) { return (b ? TRUE : FALSE)。舉個例子,對于布爾型,最常用的便是true and false。 3. java中,什么叫不可更改的類(immutable class)(Kevin Tam)從字面意思來理解就是不會發(fā)生變化的類,那么是什么不會發(fā)生變化呢,其實就是類的狀態(tài),也就是不變類的實例一旦被創(chuàng)建,其狀態(tài)就不會發(fā)生變化,舉個例子:如果人是一個class,那么我們中的每一個都是人這個類的具體的instance,如果人這個類只有一個狀態(tài)就是生身父母,那么它就是一個不變類,因為每一個人在出生的那一剎那,生身父母就已經(jīng)被設(shè)置了值,而且終生都不會發(fā)生變化。 JVM規(guī)范定義了兩種類型的ClassLoader:Bootstrap ClassLoader和Userdefined ClassLoader。 (這里出現(xiàn)JVM無法控制的內(nèi)存溢出問題native heap OutOfMemory ) 2. CLassLoader (Vincent)Java的可執(zhí)行文件不同于C/C++,Java編譯器只產(chǎn)生中間字節(jié)碼文件(.class文件),由Java虛擬機()解釋執(zhí)行。當(dāng)某個線程調(diào)用一個本地方法時,它就進入了一個全新的并且不再受虛擬機限制的世界。Program counter 每個運行中的Java程序,每一個線程都有它自己的PC寄存器,也是該線程啟動時創(chuàng)建的。 (10000)。每當(dāng)線程調(diào)用一個方法的時候,就對當(dāng)前狀態(tài)作為一個幀保存到j(luò)ava stack中(壓棧);當(dāng)一個方法調(diào)用返回時,從java stack彈出一個幀(出棧)。 (: PermGen full)Java stack 緊接著虛擬機提取其中的類型信息,并將這些信息存儲到方法區(qū)。每一個java程序獨占一個JVM實例,因而每個java程序都有它自己的堆空間,它們不會彼此干擾。 Runtime data area的整體架構(gòu)圖Runtime data area 主要包括五個部分:Heap (堆), Method Area(方法區(qū)域), Java Stack(java的棧), Program Counter(程序計數(shù)器), Native method stack(本地方法棧)。 Native interface組件 :與native libraries交互,是其它編程語言交互的接口。 Execution engine子系統(tǒng)的作用 :執(zhí)行classes中的指令。 主要包括兩個子系統(tǒng)和兩個組件: Class loader(類裝載器) 子系統(tǒng),Execution engine(執(zhí)行引擎) 子系統(tǒng);Runtime data area (運行時數(shù)據(jù)區(qū)域)組件, Native interface(本地接口)組件。摩根面試準(zhǔn)備要點1. JVM架構(gòu)(Vincent) 每個運行中的線程都有一個Execution engine的實例。 下面對這個部分進行詳細(xì)介紹。而一個Java虛擬實例中只存在一個堆空間,因此所有線程都將共享這個堆。當(dāng)虛擬機裝載某個類型時,它使用類裝載器定位相應(yīng)的class文件,然后讀入這個class文件內(nèi)容并把它傳輸?shù)教摂M機中。比如,假設(shè)同時兩個線程都企圖訪問一個名為Lava的類,而這個類還沒有內(nèi)裝載入虛擬機,那么,這時應(yīng)該只有一個線程去裝載它,而另一個線程則只能等待。虛擬機只會直接對Java stack執(zhí)行兩種操作:以幀為單位的壓棧或出棧。public class TestStackOverFlow { public static void main(String[] args) { Recursive r = new Recursive()。 }} Native method stack 對于一個運行中的Java程序而言,它還能會用到一些跟本地方法相關(guān)的數(shù)據(jù)區(qū)。總之,本地方法具有和JVM相同的能力和權(quán)限。下面我們用例子說明ClassLoader。AppClassLoader的Parent是ExtClassLoader,而ExtClassLoader的Parent為Bootstrap ClassLoader。對于不變類而言,一個好處就是可以將常用的實例進行緩存,從而減少了對象的創(chuàng)建。 /** * The codeBoolean/code object corresponding to the primitive * value codefalse/code. */public static final Boolean FALSE = new Boolean(false)。public final class String{ /** Cache the hash code for the string */private int hash。 }} 在JDK中, String, the primitive wrapper classes, and BigInteger and BigDecimal都是不變類。如果使用new去創(chuàng)建String,那么每次都會創(chuàng)建一個新對象。t create a new object checkInstance(A