121 项目 024 笔记向 内省机制

本文详细介绍了Java内省机制的基本概念及其应用场景。通过具体实例演示了如何使用Introspector类获取BeanInfo信息,并通过BeanInfo获取属性描述器(PropertyDescriptor),进而获取属性对应的getter和setter方法。此外,还展示了如何利用内省机制动态创建对象并设置属性。

内省基本概念

内省(IntroSpector)是Java语言对Bean类属性、事件的一种缺省处理方法。如类A中有属性name,那我们可以通过getName,setName来得到其值或设置新的值。通过getName/setName来访问name属性,这就是默认的规则。

Java中提供了一套API用来访问某个属性的getter/setter方法,通过这些API可以使你不需要了解这个规则,这些API在java.beans中,一般的做法是通过Introspector的getBeanInfo方法来获取某个对象的BeanInfo信息,然后通过BeanIfno来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后就可以通过反制机制来调用这些方法

Introspector 相关 API

  1. Introspector类

Introspetor类为通过工具学习有关受目标JavaBean支持的属性、事件和方法的知识提供了一个标准方法:

static BeanInfo getBeanInfo(Class<?> beanClass)

在JavaBean上进行内省, 了解其所有属性 ,公开的方法和事件

  1. BeanInfo类

该类实现此BeanInfo接口并提供有关其bean的方法、属性、事件等显示信息

MethodDescriptor[] getMethodDescriptors()

获得beans MethodDescriptor

PropertyDescriptro[] getPropertyDescriptors()

获得beans PropertyDescriptor

  1. PropertyDescriptor 类

PropertyDescriptor描述JavaBean通过一对存储器方法导出的一个属性

Method getReadMethod()

获取读取属性的方法

Method getWriteMethod()

获得用于定稿属性值的方法

  1. MethodDescriptor类

MethodDescriptor描述了一种特殊方法

即JavaBean支持从其它脑袋瓜地其进行外部访问

Method getMethod()

获得此MethodDescriptro封闭的方法

user

package com.laolang.se.fanshe.domain;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 被代理类
 */
public class User  {

    private static final Logger log = LoggerFactory.getLogger(User.class);

    public User() {
        log.info("调用无参构造函数");
    }

    public User(Long id, String name, Integer age) {
        log.info("调用带参构造函数");
        this.id = id;
        this.name = name;
        this.age = age;
    }

    private String say(){
        return name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    private Long id;

    private String name;

    private Integer age;


}

UserFactory

package com.laolang.se.fanshe;


import com.laolang.se.fanshe.domain.User;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

public class UserFactory {

    private static  Properties config = new Properties();

    static {
        InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("bean.properties");
        // 加载属性文件
        try {
            config.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static User getUser(String name) {
        String className = config.getProperty(name);
        try {
            Class<?> clazz = Class.forName(className);
            User user = (User) clazz.newInstance();
            // 内省:获取bean信息
            BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
            // 通过bean信息获取所有属性描述器
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                if("name".equals(propertyDescriptor.getName())){
                    String userName = config.getProperty("user.name");
                    Method method = propertyDescriptor.getWriteMethod();
                    method.invoke(user,userName);
                }else if ("age".equals(propertyDescriptor.getName())){
                    Method method = propertyDescriptor.getWriteMethod();
                    method.invoke(user,Integer.parseInt(config.getProperty("user.age")));
                }else if ( "id".equals(propertyDescriptor.getName())){
                    Method method = propertyDescriptor.getWriteMethod();
                    method.invoke(user,Long.parseLong(config.getProperty("user.id")));
                }
            }

            return user;


        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IntrospectionException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }
}

Main

package com.laolang.se.fanshe;


import com.laolang.se.fanshe.domain.User;

public class Main {

    public static void main(String[] args) {
        User user = UserFactory.getUser("user");
        System.out.println(user);

    }
}

bean.properties

# 配置JavaBean信息
user=com.laolang.se.fanshe.domain.User
user.name=小代码
user.age=23
user.id=1

转载于:https://my.oschina.net/iamhere/blog/858896

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值