话不多说,先上代码:
配置文件
bean.properties
accountDao=cn.study.dao.impl.IAccountDaoImpl
accountService=cn.study.service.impl.IAccountServiceImpl
下面是我的java文件
BeanFactory.java 文件
public class BeanFactory {
//定义成员变量,用于读取加载配置文件
private static Properties pro;
private static Map<String,Object> beans = new HashMap<String,Object>();
//初始化成员变量
static{
try {
//创建Properties对象
pro = new Properties();
//获取配置文件的流对象
InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
//加载配置文件
pro.load(is);
//读取配置中所有keys
Enumeration keys = pro.keys();
//遍历keys,初始化beans
while(keys.hasMoreElements()){
String key = (String)keys.nextElement();
String beanPath = pro.getProperty(key);
//创建实例对象
Object bean = Class.forName(beanPath).newInstance();
//将key 和 value存放到Map集合中。
beans.put(key,bean);
}
} catch (IOException e) {
throw new ExceptionInInitializerError("初始化失败了");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 通过classname 获取组件对象
* @param beanName
* @return
*/
public static Object getBean(String beanName){
return beans.get(beanName);
}
}
IAccountDao.java
public interface IAccountDao {
void saveAccount();
}
IAccountDaoImpl.java
public class IAccountDaoImpl implements IAccountDao {
@Override
public void saveAccount() {
System.out.println("保存成功");
}
}
IAccountService.java
public interface IAccountService {
void saveService();
}
IAccountServiceImpl.java
public class IAccountServiceImpl implements IAccountService {
private IAccountDao accountDao = (IAccountDao) BeanFactory.getBean("accountDao");
@Override
public void saveService() {
accountDao.saveAccount();
System.out.println(accountDao);
}
}
测试文件:
public class Test {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
IAccountService as = (IAccountService) BeanFactory.getBean("accountService");
System.out.println(as);
as.saveService();
}
}
}
运行结果:
Exception in thread "main" java.lang.NullPointerException
cn.study.service.impl.IAccountServiceImpl@7852e922
at cn.study.service.impl.IAccountServiceImpl.saveService(IAccountServiceImpl.java:12)
at cn.study.client.Client.main(Client.java:11)
[ERROR] Command execution failed.
首先说,如果将配置文件中的顺序改变如下,就不会报错
accountService=cn.study.service.impl.IAccountServiceImpl
accountDao=cn.study.dao.impl.IAccountDaoImpl
这是为什么呢?
DEBUG分析
在BeanFactory中
pro.load(is)后,
可以发现,与配置文件中的数据已经改变
从pro中先读取到的的是accountService
而经过Class.forName(beanPath).newInstance()获取到的accountService为:
可以看见accountDao为null
所以会accoutnDao.save调用时会发生空指针异常
因为创建accountServiceImpl实例时,成员变量account为null;