基本概念:
内省(Introspector)是Java语言对Bean类属性、事件的一种缺省(默认)处理方法。例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新的值。
通过getName/setName来访问name属性,这就是默认的规则。
Introspector相关API
1、Introspector类 :
Introspector类为通过工具学习有关受目标Java Bean支持的属性、事件和方法的知识提供了一个标准方法。
static BeanInfo getBeanInfo(Class<?> beanClass)
在Java Bean上进行内省,了解其所有属性、公开的方法和事件。
2、BeanInfo类 :
该类实现此BeanInfo接口并提供有关其bean的方法、属性、事件等显式信息。
MethodDescriptor[] getMethodDescriptors()
获得beans MethodDescriptor.
PropertyDescriptor[] getPropertyDescriptors()
获得beans PropertyDescriptor.
Properties属性文件工具类的使用
3、PropertyDescriptor 类:
PropertyDescriptor描述Java Bean通过一对存 储器方法导出的一个属性。
Method getReadMethod()
获得应该用于读取属性值的方法。
Method getWriteMethod()
获得应该用于写入属性值的方法。
4、MethodDescriptor 类:
MethodDescriptor描述了一种特殊方法,
即JavaBean支持从其他组件对其进行外部访问。
Method getMethod()
获得此MethodDescriptor封装的方法。
代码示例:
通过反射加内省实现对Properties属性文件的装配
测试类:
package com.introspector;
import org.junit.jupiter.api.Test;
public class BeanTest {
@Test
public void getBeanTest(){
Config bean = (Config)BeanFactory.getbean("Bean.config");
System.out.println(bean);
}
}
实现主类BeanFactory:
package com.introspector;
import java.beans.*;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class BeanFactory {
private static Properties pro = new Properties();
//使用静态代码块加载配置文件
static {
//当前线程的类加载器获取文件
InputStream res = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/introspector/config.properties");
try {
pro.load(res);//加载文件输入流
} catch (IOException e) {
e.printStackTrace();
}
}
//获取bean(java类)
public static Object getbean(String name){
Object bean = null;
//获取获取文件中的beanname
String beanname = pro.getProperty(name);
//通过beanname反射得到类信息
try {
Class<?> aClass = Class.forName(beanname);
bean = aClass.newInstance();
//通过类信息获取类描述信息
BeanInfo beanInfo = Introspector.getBeanInfo(aClass);
//通过类描述信息得到类所有属性描述器
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
//遍历类属性描述器
for (int i = 0; i <propertyDescriptors.length ; i++) {
String propertyname = propertyDescriptors[i].getName();
Method writeMethod = propertyDescriptors[i].getWriteMethod();
if("username".equals(propertyname)){
//调用属性的set方法
writeMethod.invoke(bean,pro.getProperty("Bean.username"));
}else if("password".equals(propertyname)){
writeMethod.invoke(bean,pro.getProperty("Bean.password"));
}else if("url".equals(propertyname)){
writeMethod.invoke(bean,pro.getProperty("Bean.url"));
}
}
} catch (ClassNotFoundException | InvocationTargetException | IllegalAccessException | IntrospectionException | InstantiationException e) {
e.printStackTrace();
}
return bean;
}
}
数据对象类Config:
package com.introspector;
public class Config {
private String username;
private String password;
private String url;
public Config(String username, String password, String url) {
this.username = username;
this.password = password;
this.url = url;
}
public Config() {
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public String toString() {
return "Config{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", url='" + url + '\'' +
'}';
}
}
配置文件:
config.properties
Bean.config = com.introspector.Config
Bean.username = admin
Bean.password = 12345
Bean.url = www.baidu.com