以属性文件的方式模拟IOC
1. 创建properties文件
在resources目录下创建一个properties属性文件
2. 编写自己的spring容器
public class SpringApplicationContext {
private Map<String,Object> map=new HashMap<String,Object>();
public SpringApplicationContext(String fileName){
ResourceBundle bundle = ResourceBundle.getBundle(fileName);
Enumeration<String> keys = bundle.getKeys();
while(keys.hasMoreElements()){
String key=keys.nextElement();
String className=bundle.getString(key);
try {
Class clazz= Class.forName(className);
//采用无参构造方法创建对象
Object obj=clazz.newInstance();
map.put(key,obj);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public Object getBean(String name){
return map.get(name);
}
}
3. 测试
@Test
public void testSpringApplicationContext(){
SpringApplicationContext sac=new SpringApplicationContext("beans");
PersonDao personDao=(PersonDao)sac.getBean("personDao");
personDao.savePerson("王五");
}
基于xml的IOC容器实现
1. 创建一个maven Java工程
2. 引入依赖
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
3. 创建PersonDao接口
public interface PersonDao {
public void savePerson(String name);
public void updatePerson(String name,int id);
public void deletePerson(int id);
public String getNameById(int id);
public List<String> getNames();
}
接口的实现类
public class PerosnDaoImpl implements PersonDao {
@Override
public void savePerson(String name) {
System.out.println("name为"+name+"的记录保存成功");
}
@Override
public void updatePerson(String name, int id) {
System.out.println("name为"+name+"id为"+id+"的记录更新成功");
}
@Override
public void deletePerson(int id) {
System.out.println("id"+id+"的记录删除成功");
}
@Override
public String getNameById(int id) {
List<String> names= Arrays.asList("张三","李娜","王文","田园");
return names.get(id-1);
}
@Override
public List<String> getNames() {
List<String> names= Arrays.asList("张三","李娜","王文","田园");
return names;
}
}
4. PersonService接口
public interface PersonService {
public void savePerson(String name);
public void updatePerson(String name,int id);
public void deletePerson(int id);
public String getNameById(int id);
public List<String> getNames();
}
实现类
public class PersonServiceImpl implements PersonService {
private PersonDao personDao;
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
@Override
public void savePerson(String name) {
personDao.savePerson(name);
}
@Override
public void updatePerson(String name, int id) {
personDao.updatePerson(name,id);
}
@Override
public void deletePerson(int id) {
personDao.deletePerson(id);
}
@Override
public String getNameById(int id) {
return personDao.getNameById(id);
}
@Override
public List<String> getNames() {
return personDao.getNames();
}
}
5. 创建一个xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="personDao" class="cn.offcn.dao.impl.PerosnDaoImpl"></bean>
<bean id="personService" class="cn.offcn.service.impl.PersonServiceImpl">
<property name="personDao" ref="personDao"></property>
</bean>
</beans>
6. 自定义spring容器
public class SpringApplicationContext {
private Map<String,Object> map=new HashMap<String,Object>();
public SpringApplicationContext(String fileName){
try {
//1.创建SAXReader对象
SAXReader saxReader=new SAXReader();
//2. 读取xml文件返回一个文档对象
Document document = saxReader.read(fileName);
//3.获取xml文档的根元素对象
Element rootElement = document.getRootElement();
//4.从根元素下找到所有的bean子元素对象
List<Element> beanElementList = rootElement.elements("bean");
//5.循环beanElementList,找到每个bean元素对象
for (Element element : beanElementList) {
//找到bean元素的id属性的值
String key= element.attributeValue("id");
//找到bean元素的class属性的值
String className= element.attributeValue("class");
//获取该bean所描述类的Class类的对象
Class clazz=Class.forName(className);
Object obj=clazz.newInstance();
map.put(key,obj);
//找bean标签下的所有的property子签标对象集合
List<Element> propertyElementList = element.elements("property");
if(propertyElementList!=null && propertyElementList.size()>0){
//循环property元素
for (Element propertyElement : propertyElementList) {
//找到property标签中的name属性的值
String feildName=propertyElement.attributeValue("name");
//找到property标签中的ref属性的值
String ref=propertyElement.attributeValue("ref");
//从容器中取key为ref所描述的key的值
Object value=map.get(ref);
byte[] bytes= feildName.getBytes();
bytes[0]=(byte)(bytes[0]-32);
String methodName="set"+new String(bytes);
Class<?>[] interfaces = value.getClass().getInterfaces();
Method metod = clazz.getDeclaredMethod(methodName, interfaces[0]);
metod.invoke(obj,value);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public Object getBean(String name){
return map.get(name);
}
}
7. 测试
public class SpringApplicationContextTest {
@Test
public void testSpringApplicationContext(){
SpringApplicationContext ctx=new SpringApplicationContext("F:\\java803\\workspace\\XmlSpringContainer\\src\\main\\resources\\beans.xml");
PersonService ps=(PersonService) ctx.getBean("personService");
ps.savePerson("张三峰");
}
}