java的内省有用么_java Introspector(内省) 的使用场景以及为什么使用

内省一般写业务代码的时候是用不到的,大部分是在写一些框架或者工具的时候会用到。

比如说 spring 初始化 bean 的场景:

spring 提供 ioc 的机制,使用者在 xml 中配置 bean,spring 启动的时候加载 bean

假设有下面的类:

public class User {

private String name;

private int age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

我们正常使用的话,可以这样写:

User u = new User();

u.setName("chengfan");

u.setAge(22);

这是完全没有问题的,但是,当我们把这个类交给 spring 的时候,问题就出现了: spring 是一个已有的框架, 它并不知道 User 这个类,也并不知道它有哪些方法、哪些属性。

所以 spring 需要使用一种特殊的手段来拿到这些信息,我们熟知的方法是反射。

spring.xml 如下:

利用反射,我们会这样写:

@Test

public void test1 () throws Exception {

//模拟从 xml 中获得到了数据

//

//

//

//

String clazz = "cn.fanhub.jysk.spring.introspector.User";

Map properties = new HashMap<>();

properties.put("Name", "chengfan");

properties.put("Age", 22);

reflect(clazz, properties);

}

@SuppressWarnings("unchecked")

public void reflect(String clazz, Map properties) throws Exception {

//反射创建实例

Class target = Class.forName(clazz);

Object bean = target.newInstance();

//初始化容器时,调用setter注入

for (Entry entry : properties.entrySet()) {

String _setName = "set" + entry.getKey();

if ("name".equalsIgnoreCase(entry.getKey())) {

Method setMethod = target.getMethod(_setName, String.class);

setMethod.invoke(bean, entry.getValue().toString());

} else {

Method setMethod = target.getMethod(_setName, int.class);

setMethod.invoke(bean, Integer.parseInt(entry.getValue().toString()));

}

}

// show

for (Entry entry : properties.entrySet()) {

String _getName = "get" + entry.getKey();

if ("name".equalsIgnoreCase(entry.getKey())) {

Method setMethod = target.getMethod(_getName);

System.out.println(setMethod.invoke(bean));

} else {

Method setMethod = target.getMethod(_getName);

System.out.println(setMethod.invoke(bean));

}

}

}

/*

22

chengfan

*/

都是硬编码,不具备任何观赏性,只是为了演示如何实现。

虽然这样可以达到目的,但是我们获取 get 和 set 方法的手段不够优雅。

使用内省的方式实现如上功能:

@Test

public void test1 () throws Exception {

//模拟从 xml 中获得到了数据

//

//

//

//

String clazz = "cn.fanhub.jysk.spring.introspector.User";

Map properties = new HashMap<>();

properties.put("name", "chengfan");

properties.put("age", 22);

introspector(clazz, properties);

}

public void introspector(String clazz, Map properties) throws Exception {

//反射创建实例

Class target = Class.forName(clazz);

Object bean = target.newInstance();

BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());

PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();

for (PropertyDescriptor pd : pds) {

Method setMethod = pd.getWriteMethod();

String fieldName = pd.getName();

if ("name".equalsIgnoreCase(fieldName)) {

setMethod.invoke(bean, properties.get(fieldName));

} else if ("age".equalsIgnoreCase(fieldName)){

setMethod.invoke(bean, properties.get(fieldName));

}

}

// show

for (PropertyDescriptor pd : pds) {

System.out.println(pd.getReadMethod().invoke(bean));

}

}

/*

22

chengfan

class cn.fanhub.jysk.spring.introspector.User // 先忽略它

*/

很明显,内省显得更加专业。当然,它的操作依旧不方便,比如参数类型的判断。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值