1:引入依赖
解析xml配置文件,用到XPath和dom4j
<!--解析使用的依赖dom4j和Xpath-->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.6</version>
</dependency>
2:新建dao包,UserDao类
public class UserDao {
public void test(){
System.out.println("UserDao...");
}
}
3:新建service包,UserService类
public class UserService {
public void test(){
System.out.println("UserService...");
}
}
4:新建pojo包,MyBean类
自定义MyBean,用来描述配置文件中bean标签的id和calss
public class MyBean {
private String id;
private String clazz;
public MyBean(){
}
public MyBean(String id, String clazz) {
this.id = id;
this.clazz = clazz;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
}
5:新建factory包,MyFactory接口
自定义工厂接口,获取bean对象实例
public interface MyFactory {
//通过 id 获取bean对象
public Object getBean(String id);
}
6:factory包下,MyClassPathXmlApplication类
工厂接口的实现类:
1:获得需要解析的xml配置文件
2:通过dom4j解析的bean标签信息,生成MyBean对象,将这些MyBean对象存入集合中
3:通过MyBean对象的id,class信息,生成Bean对象的实例,存入到Map中
public class MyClassPathXmlApplication implements MyFactory {
//List存放解析的bean标签里面的id,class
private List<MyBean> beanList=null;
//Map存放实例化的Bean对象 id,Bean
private Map<String ,Object> beanMap=null;
//获取要解析的配置文件(通过带参构造器传递需要解析的配置文件)
public MyClassPathXmlApplication(String fileName) throws DocumentException, IllegalAccessException, InstantiationException, ClassNotFoundException {
//解析配置文件
this.parseXml(fileName);
//实例化Bean对象
this.instanceBean();
}
//解析xml文件方法 引入dom4j和Xpath依赖
private void parseXml(String fileName) throws DocumentException {
//1:获取解析器
SAXReader saxReader=new SAXReader();
//2:获取解析的配置文件的url地址
URL url=this.getClass().getClassLoader().getResource(fileName);
//3:解析配置文件,返回Document对象
Document document = saxReader.read(url);
//4:解析标签 得到beans下的所有bean标签
XPath xpath=document.createXPath("beans/bean");
//5:XPath语法得到要解析的指定元素
List<Element> elementList= xpath.selectNodes(document);
//6:判断标签集合是否存在
if(elementList!=null && elementList.size()>0){
//7:实例化beanList
beanList=new ArrayList<>();
//8:遍历集合
for(Element e:elementList){
//9:得到每一个标签里的id和class
String id=e.attributeValue("id");
String clazz=e.attributeValue("class");
//10:将id和class放到MyBean对象中,并放到集合中
beanList.add(new MyBean(id,clazz));
}
}
}
//实例化Bean对象方法
private void instanceBean() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
//确保beanList有值
if(beanList!=null && beanList.size()>0){
beanMap=new HashMap<>();
for(MyBean myBean:beanList){
//1:得到id
String id=myBean.getId();
//2: 通过类路径实例化Bean对象
Object o = Class.forName(myBean.getClazz()).newInstance();
//3:将id作为key Bean对象作为value 存入到Map中
beanMap.put(id, o);
}
}
}
//通过id获取map中指定的实例化对象
@Override
public Object getBean(String id) {
return beanMap.get(id);
}
}
7:测试
简单实现Spring的IOC,Bean对象实例化
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, DocumentException, IllegalAccessException {
//得到上下文环境
MyFactory factory=new MyClassPathXmlApplication("spring.xml");
//得到实例化对象
UserDao userDao1 = (UserDao) factory.getBean("userDao");
UserService userService=(UserService) factory.getBean("userService");
userDao1.test();
userService.test();
//从Map中得到的Bean对象是同一个对象
UserDao userDao2 = (UserDao) factory.getBean("userDao");
System.out.println(userDao1);
System.out.println(userDao2);
}
8:简单实现的过程
1:xml文件中,标签中的标签存储了Bean的id和class信息
2:MyBean类的成员变量是,id和class信息,用来实例化Bean对象
3:MyFactory的实现类的主要功能是解析xml文件,得到id,class的信息,通过类路径实例化Bean
Object o = Class.forName(myBean.getClazz()).newInstance();
4:所有的Bean信息(id,class)存入到List中,所有的Bean对象存入到Map中,id为键,实例化的对象为值