AOP包括两个方面:
1)代理模式
2)bytecode instrument(插桩)-- 修改java生成的字节码文件。 = CGLIB
学习Spring之前可以先看看java的反射机制。
同时要学好泛型相关的知识。
在java运行时【注意是在运行时而不是在编译时】环境,对于任何一个类,都可以知道这个类具有哪些属性和方法。
对于任何一个对象,都可以调用这个对象的方法。
动态获取类得信息和调用对象的方法 ---- 来自java的范式机制。
{获取一个对象最常用的方法是使用new,但这个属于编译期间,写在代码里面的,如果需要动态获得类,要使用java的反射机制}
java反射机制允许程序在运行时透过reflection APIS 取得任何一个已知名称的class的内部信息。【根据一个类的字符串名字,可以知道类得所有信息。】
什么是动态语言:一般认为,在运行时可以改变程序结构或者变量类型,可以称为是动态语言。c++,java,c#.是静态语言,perl,ruby,是动态语言。
关于java的reflection API
java.long.reflect包中。
java.lang.Class<T>
每一个对象都对应一个class对象。
是反射的入口点。
public static Claaa<?> forName(String className)throws ClassNotFoundException. //写全名 。比如希望参数是String类,应该传入的为java.lang.String
public Method[] getDeclaredMethods() throws SecurityException
class<?> classType = Class.forName(argo[0]);//class类是java反射的入口点。
Method[] methods = classType.getDeclaredMethods();
for(Method method:methods){
System.out.println(method);
}
在编译时并不知道args[0]是什么,所以说明了是运行期间反射出了类的全部信息。
public Method getMethod(String name,class<?>...parameterTypes)
public object invoke(Object obj, Object...paramterTypes)
public int add(int param1,int param2){
return param1+param2;
}
public static void main(String args[]){
Class<?>classType = InvokeTester.class;//会获得InvokerTest所对应的class对象
Object invokeTester = classType.newInstance();//创建这个class对象所代表的类的实例。
//以上方法等价于:
//InvokeTester i = new InvokeTester();
Method addmethod = classType.getMethod("add",new class[]{int.class,int.class});//根据方法名和参数的类型来确定反射对应的方法
Object result = addmethod.invoke("invokeTester",new Object[]{100,200});//
//以上方法等价于:
//i.add(100,200);
System.out.println((Integer)result);
}
java.long,reflect
Class constructor<?>
//传进来一个对象,根据反射返回一个拷贝的对象。
public Object copy(Object obj){
Class<?> classType = obj.getClass();//获得obj对应的class对象
Object objectCopy =classType.getConstructor(new Class[]{}).newInstance(new Object[]{});//这个也是调用无参数构造函数、
//上面的代码等价于
//Object objectCopy2 = classType.newInstance();这个只能生成一个不带参数的实例,
//通用的是上面的构造方法,如果要调用一个带参数的构造函数,只要写入参数类型和参数值就可以了。
//获得对象的所有属性
Field[] fields = classType.getDeclaredFields();
for(int i= 0; i<fields.length;i++){
Field field = field[i];
String fieldname = field.getName();//获取属性名字
String fistLetter = fieldName.subString(0,1).toUpperCase();//获得属性的第一个字母并且转换成大写,为了便于拼接
//获得与属性对应的getXXX()方法的名字
String getMethodName = "get"+ firstLetter+fieldname.subString(1);
//获取与属性对应的setXXX()方法的名字
String setMethodName = "set"+ firstLetter+fieldname.subString(1);
//取得getXXX方法
Method getMethod =classType.getMethod(getMethodName,new Class[]{})
//取得setXXX方法
Method setMethod = classType.getMethod(setMethodName,new Class[]{field.getType()})
//调用getXXX方法
Object value =getMethod.invoke(obj,new Object[]{});//get方法不传入参数
System.out.println(fieldname +":"+value);
//调用setXXX方法
setMethod.invoke(objectCopy,new Object[]{value});//给新实例化的对象设置属性值
}
return objectCopy;//返回拷贝的值
}