内省:
通过内省Api来装配一个bean对象,bean对象的值是通过配置文件来获取
即通过配置文件中的属性和特定的类信息来,来组装一个对象,便于维护;
内省机制是通过反射来实现的,BeanInfo用来暴露一个bean的属性、方法和事件,以后我们就可以操纵该JavaBean的属性
首先生成一个利用类的无参构造器生成一个对象,再利用BeanInfo 给这个对象添加属性; 注意:该类必须设置一个无参构造器。或者实例化的时候注意需要带上相应的参数;
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 Demo {
public static void main(String[] args) {
try {
Config bean = ((Config) BeanFactory.getBean("bean.name"));
System.out.println(bean);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
class Config{
private String username;
private String password;
private String url;
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 + '\'' +
'}';
}
}
class BeanFactory{
private static Properties p = new Properties();
//使用静态代码块读取配置文件
static {
InputStream inStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com\\first\\conf.properties");
try {
p.load(inStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static Object getBean(String name) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
String beanName = p.getProperty(name);
//获取类信息
Class<?> aClass = Class.forName(beanName);
//实例化一个bean对象
Object bean = aClass.newInstance();
try {
//通过类信息,获取javaBean的描述信息,所以 内省 基于 反射 进行
BeanInfo beanInfo = Introspector.getBeanInfo(aClass);
//通过描述信息,获取该类的所有属性描述器,该类必须将属性字段设置get和set方法;(才能获取)
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,p.getProperty("user.name"));
}else if("password".equals(propertyName)){
writeMethod.invoke(bean,p.getProperty("user.password"));
}else if("url".equals(propertyName)){
writeMethod.invoke(bean,p.getProperty("url"));
}
}
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return bean;
}
}
配置文件 com\first\conf.properties
bean.name=com.first.Config
user.name=admin
user.password=admin
url=http://www.baidu.com