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:该类即为动态代理类。