一次课堂中,听到有Spring的内省,之前都没有听到这个词,那么究竟什么Spring的内省,从前我只认为我懂了反射,自己快工作三年了,还是在工作中没有怎么运用,觉得工作就是写一些业务代码,没有用到什么高深的技术,很向往那种技术大牛,为什么他们能短暂的时间能掌握到一个技术这么深,而自己只有这么浅,这样一想,很快感到深深的自卑。但是
也激发自己求知欲。好了,废话不多说.
反射是在程序运行过程中,可以动态的获取所有的属性、方法、构造器以及动态操作任意方法、狗仔器和修改属性值等。 而内省机制是通过BeanInfo用来暴露一个bean的属性、方法和事件,以后我们就可以操纵该JavaBean的属性。
首先新建一个实体bean User:
public classUser {private longid;privateString name;public longgetId() {returnid;
}public void setId(longid) {this.id =id;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}
@OverridepublicString toString() {return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
内省机制的实现,通过introspector获取一个的类的BeanInfo,第二个参数是到哪个类停止,获取到的Beandescriptor是这个bean的所有描述。里面包含
MethodDescriptor和 PropertyDescrptor分别描述的Bean的所有方法的描述和所有属性的描述。
User user = new User();
BeanInfo descriptor = Introspector.getBeanInfo(user.getClass(), Object.class);
BeanDescriptor beanDescriptor = descriptor.getBeanDescriptor();
System.out.println(beanDescriptor);
MethodDescriptor[] descriptor1 = descriptor.getMethodDescriptors();
for (MethodDescriptor methodDescriptor : descriptor1) {
System.out.println(methodDescriptor.toString());
}
PropertyDescriptor[] descriptor2 = descriptor.getPropertyDescriptors();
Stream.of(descriptor2).forEach(k -> {
String name = k.getName();
System.out.println("name:"+name);
try {
if("id".equals(k.getName())) {
k.getWriteMethod().invoke(user, new Object[]{10});
}
}catch (Exception e){
e.printStackTrace();
}
});
而反射是程序运行时,获取类的属性和方法和构造器,, 并获取对应的方法,执行的对应的方法的。
Field[] fields = User.class.getDeclaredFields();for(Field field : fields){
System.out.println(field.getName());
}
Method[] methods= User.class.getMethods();for(Method field : methods){
System.out.println(field.getName());
}
反射遍历属性的时候是没有方法拿到他get set方法的,但是可以手动实现。如下代码
Class userClz = Class.forName(User.class.getName());
Field[] fields=userClz.getDeclaredFields();for(Field field : fields){
System.out.println(field.getName());if("id".equals(field.getName())) {
Method getMethod= userClz.getDeclaredMethod("get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1));
System.out.println("geteMethod:" +getMethod.getName());try{
Method wrtieMethod= userClz.getDeclaredMethod("set" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1), new Class[]{Long.class});
System.out.println("geteMethod" +wrtieMethod.getName());
}catch(Exception e){
e.printStackTrace();
}
}
}
Method[] methods= User.class.getMethods();for(Method method : methods){
System.out.println(method.getName());
}
}
总的来时, java的内省是通过反射实现的,内省的使用场景是对于属性的操作更加便利,而反射则更使用调用除了get, set方法外的其他方法,就像springMVC中,
HandlerMapping, 是一个url对应一个Method, 当匹配到url的时候,会动态调用对应Controller里的方法。