spring源代碼,其基本原理如依賴注入、aop、以及xml技術,動態反射機制
Reflection
學習反射原理,了解幾個重要的類會比較好:java.lang.Class, java.lang.reflect中的Method、Field、Constructor等classes。
java反射機制主要提供了以下功能:
- 在運行時判斷任意一個對象所屬的類
- 在運行時構造任意一個類的對象
- 在運行時判斷任意一個類所具有的成員變量和方法
- 在運行時調用任意一個對象的方法
demo
class Person{
private long id;
private int age;
private String name;
public Person(){
}
public Person(String name, int age){
this.name = name;
this.age = age;
}
@Override
public String toString(){
return "Name="+getName()+" Age ="+getAge()+" Id"+getId();
}
public long getId(){
return id;
}
public void setId(long id){
this.id = id;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public static void main(String[] args) throws Exception{
//獲取Person類的Class對象
Class<?> classType = Class.forName("Person");
//調用Person類的兩個參數構造函數構造方法生成對象
Constructor constructor = classType.getConstructor(new Class[]{String.class, int.class});
Object object = constructor.newInstance(new Object[]{"Dean",25});
//獲取SetId方法
Method setId = classType.getMethod("setId",new Class[]{long.class});
//調用setId方法設置Id
setId.invoke(object, new Object[]{10});
//調用toString輸出結果
Method toString = classType.getMethod("toString",new Class[]{});
String result = (String)toString.invoke(object,new Object[]{});
System.out.println(result);
}
}
- 基于類的反射
- 基于字段的反射
- 基于方法的反射
- 數組的反射
introspection: the ability of the program to examine itself.
在JDK中,主要由以下類來實現Java反射機制,這些類都位于java.lang.reflect包中
-Class類:代表一個類
-Method類:代表類的成員變量
-Constructor類:代表類的構造方法
-Array類:提供了動態創建數組,以及訪問數組的元素的靜態的方法
在java.lang.Object類中定義了getClass()方法,因此對于任意一個Java對象,都可以通過此方法獲得對象的類型。
Class類是Reflection API中的核心類,它有以下方法
-getName();
-getFields();
-getDeclaredFields();
-getMothods();
-getDeclaredMethods();
-getConstructors();
-getConstructor(Class[] parameter Types);
-newInstance();
通過默認構造方法創建一個新對象
Object objectCopy = classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
獲得對象的所有屬性:
Field fields[]=classType.getDeclaredFields();
. Class類的getDeclaredFields()方法返回類的所有屬性,包括public,protected,默認和private訪問級別的屬性
Method類的invoke(Object obj,Object args[])方法接收的參數必須為對象,如果參數為基本類型數據,必須轉換為相應的包裝類型的對象。invoke()方法的返回值總是對象,如果實際被調用的方法的返回類型是基本類型數據,那么invoke()方法會把它轉換為相應的包裝類型的對象,再將其返回。
獲得某個類或某個對象所對應的Class對象的常用的3種方式:
a. 使用Class類的靜態方法forName:
Class.forName("java.lang.String");
b. 使用類的.class語法:
String.class;
c. 使用對象的getClass()方法:
String s = "aa";
Class<?> clazz = s.getClass();
下面寫一個程序來用以下這些API吧:
若想通過類的不帶參數的構造方法來生成對象,我們有兩種方式:
- 先獲得Class對象,然后通過該Class對象的newInstance()方法直接生成即可:
Class<?>classType = String.class;
Object obj = classType.newInstance(); - 先獲得Class對象,然后通過該對象獲得對應的Constructor對象,再通過該Constructor對象的newInstance()方法生成:
Class<?>classType = Customer.class;
Constructor cons = classType.getConstructor(new Class[]{});
Object obj = cons.newInstance(new Object[]{});
若想通過類的帶參的構造方法生成對象,只能使用下面的這一種方式:
- Class<?>classType = Customer.class;
Constructor cons = classType.getConstructor(new Class[]{String.class,int.class});
Object obj = cons.newInstance(new Object[]{"hello",3});
實例中的經典應用
- 得到某個對象的屬性
- 得到某個類的靜態屬性
- 執行某對象的方法
- 執行某個類的靜態方法
- 新建實例
- 判斷是否為某個類的實例
- 得到數組的某個元素
代理
代理模式的作用是:為其他對象提供一種代理以控制對這個對象的訪問。
*在某些情況下,一個客戶不想或不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用
代理模式一般涉及到的角色有:
*抽象角色
*代理角色
*真實角色
java的動態代理位于java.lang.reflect包下,一般主要涉及到以下兩個類
interface InvocationHandler:該接口中僅定義了一個方法
-public object invoke(Object obj,Method method,Object[] args)Proxy:該類即為動態代理類。