1、原来写IOC的原理时总是默认知道方法名(属性名),然后通过反射机制来调用方法(给属性赋值);但突然想到,其实程序运行时,是不知道方法名(属性名)的,那么反射机制该如何运行?如是有了下面的代码
/**
*知道方法名(属性名)的写法
field = clazz.getDeclaredField("engine");
field.setAccessible(true);
field.set(privateCar, field.getType().newInstance());
Method method = clazz.getDeclaredMethod("drive");
method.setAccessible(true);
method.invoke(privateCar);
*/
实际上的写法
package com.keivndai.comomtest;
import org.springframework.beans.factory.annotation.Autowired;
public class PrivateCar {
private String color;
@Autowired
private Engine engine;
private Integer i;
protected void drive(){
System.out.println("drive my " + color + " car!");
System.out.println("THE engine brand : " + engine.brand);
System.out.println("init int " + i);
}
}
package com.keivndai.comomtest;
public class Engine {
public static String brand = "benz";
}
package com.kevindai.test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class AbstactReflect {
public static void main(String[] args) throws Exception {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class<?> clazz = cl.loadClass("com.kevindai.test.PrivateCar");
Object o = clazz.newInstance();
Field[] fields = clazz.getDeclaredFields();
for(Field f : fields){
Annotation[] annotation = f.getDeclaredAnnotations();
if(annotation.length > 0){
if(!f.isAccessible()){
f.setAccessible(true);
}
//找到当前属性的类型并新建一个对象赋值给属性(类似spring注入一个实体)
Class<?> cla = f.getType();
Object object = cla.newInstance();
//这样注入有一个问题,当属性没有无参构造函数(如Integer)时会有问题,且不用对基本数据类型这样注入
f.set(o,object);
}
}
Method[] methods = clazz.getDeclaredMethods();
for(Method m :methods){
if(!m.isAccessible()){
m.setAccessible(true);
}
m.invoke(o);
}
}
}