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