1.spring 體系結構:
spring的五個模塊:IOC,AOP,數據訪問和集成,Web及遠程操作,測試框架;
IOC:BeanFactory接口是Spring框架的核心接口,實現類與類之間的依賴可以從代碼中脫離出來,用配置文件的方式進行依賴關係的描述;
Context模塊構建與核心模塊之上,拓展了BeanFactory的功能,實現Bean生命週期控制,il8n國際化,框架事件體系,資源加載透明化等體系,另外還提供了許多企業級的服務,如郵件服務,任務調度,JNDI定位,EJB集成,遠程訪問等。ApplicationContext是Context模塊的核心接口;
AOP:面向切面編程;
數據訪問和集成:藉助AOP技術,實現了數據庫持久層框架的訪問;在實際項目中的DAO層;可以通過jdbc,Hibernate,iBatis來實現;包括JDBC ORM OXM JMS ;
Web及遠程操作:該模塊建立在ApplicationContext模塊之上,提供了Web應用的各種工具類;可以整合Structs、WebWork等WEB框架;當然,spring也提供了自己的框架SpringMVC
測試框架:
2.IOC:
JAVA反射機制:
@Override
public Car initByDefaultConst() {
//1通過類裝載器加載Car對象
ClassLoader loader=Thread.currentThread().getContextClassLoader();
Car car=null;
try {
//2.獲取類的默認構造器對象並通過它實例化Car
Class clazz=loader.loadClass("beans.Car");
Constructor cons=clazz.getDeclaredConstructor((Class[])null);
car=(Car)cons.newInstance();
//3.通過反射方法設置屬性
Method setBrand=clazz.getMethod("setBrand", String.class);
setBrand.invoke(car, "蘭博基尼");
Method setColor=clazz.getMethod("setColor", String.class);
setColor.invoke(car, "red");
Method setMaxSpeed=clazz.getMethod("setMaxSpeed", int.class);
setMaxSpeed.invoke(car, 200);
Method setAll=clazz.getMethod("setAll", String.class,String.class);
setAll.invoke(car, "邁巴赫","棕綠色");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return car;
}
類加載器ClassLoader:
類加載器就是尋找類的字節碼文件並構造出類在JVM內部表示的對象組件;在java中,類裝載器把一個類裝入JVM中,要經過以下步驟:
1.裝載:查找和導入Class文件;
2.鏈接:執行校驗、準備和解析步驟,其中解析步驟是可以選擇的:
a)校驗:檢查載入Class文件數據的正確性;
b)準備:給類的靜態變量分配空間;
c)解析:將符號引用轉成直接引用;
3.初始化:對類的靜態變量、靜態代碼執行初始化工作;
類裝載工作由ClassLoader及其子類負責;JVM運行時會產生3個ClassLoader:AppClassLoader(系統類裝載器)、ExtClassLoader(擴展類裝載器)、根裝載器;這三個依次繼承;但在JAVA中,根裝載器由C++編寫,故看不到;在java中所有的類裝載都是由這三個類裝載器協作共同完成的;
那麼這三個類又是如何分工的呢?
根裝載器負責JRE的核心類庫,eg:JRE目錄下的rt.jar、charsets.jar等;
擴展類裝載器(ExtClassLoader)負責裝載JRE擴展目錄ext中的JAR類包;
系統類裝載器(AppClassLoader)負責裝載Classpath路徑下的類包;
現在我們來假設,有一個用戶自己寫了一個惡意的java基礎類(如java.lang.String),那麼這個類一旦被加載到JVM後,其後果不堪設想;那麼JVM又是怎麼去處理的呢?
JVM在裝載類時,有一個默認機制:全盤負責委託機制;全盤負責是指一個類加載器加載一個類時,該類的依賴及引用的類也全部由該加載器加載;所以,一個class在JVM中有且僅有一個ClassLoader;委託機制是指我們在加載一個類時,先委託父裝載器尋找目標類,如果找不到。在從自己的類路徑中查找;這樣,即使惡意的類,但不會被加載;因爲加載java.lang.String時,先由根類裝載器掃描其對應路徑是否有目標類,如果有,則加載;沒有再委託給其子類掃描;所以,即使惡意的類,永遠還沒被掃描到,就已經使用系統加載的類加載完畢;
關於錯誤信息java.lang.NoSuchMethodError的錯誤信息:通常是由於多個版本的類包,在進行加載時,沒有加載到對應版本;
4.ClassLoader重要方法:(ClassLoader是一個抽象類,位於java.lang中);
Class loadClass(String name); 加載指定類;name參數是需要裝載的類的全限定類名;該方法有一個重載loadClass(String name, boolean resolve); resolve告訴裝載器是否要解析該類;
Class defineClass(String name,byte[] b,int off,int len);將類文件的字節數組轉換爲JVM內部的java.lang.Class對象;字節數組可以從本地文件系統、遠程網絡獲取;
Class findSystemClass(String name); 從本地文件載入Class文件;JVM默認的裝載機制;
Class findLoadedClass(String name);查看classLoader是否已裝入某個類;如果已裝入,則返回java.lang.Class對象,否則,返回null;如果強行裝載已存在的類,則會拋出鏈接錯誤;
ClassLoader getParent();獲取弗雷==類裝載器的父類裝載器;
5.Java反射機制:(可以從Class對象中獲取構造參數、成員變量、方法類元素的反射對象,並以編程的方式通過這些反射對象對目標對象;這些反射類在java.reflect包中定義);
Constructor:類的構造函數反射類;通過getConstructors()方法獲得所有構造函數反射對象數組。並且可以通過newInstance();獲得實例;
Method:類方法的反射類,通過getDeclareMethods()方法獲取類的所有方法反射類對象數組;並通過invoke調用;
Field:類的成員變量的反射類,通過getDeclaredFields()方法獲取類的成員變量反射對象數組;
在訪問private、protected成員變量和方法時必須通過setAccessible(boolean access)方法取消java語言檢查,否則將拋出IllegalAccessException;