模拟Spring的ClassPathXMLApplicationContext类,从xml配置文件中读取然后完成bean的实例化以及bean的属性的依赖注入
1.定义配置文件
<beans> <bean id="user" class="com.spring.pojo.User"> <property name="id" value="789"></property> <property name="name" value="cisdi"></property> <property name="pwd" value="123"></property> </bean> <bean id="userDao" class="com.spring.dao.impl.UserDaoImpl"></bean> <bean id="userService" class="com.spring.service.impl.UserServiceImpl"> <property name="userDao" ref="userDao"></property> </bean> </beans>
2.定义一个BeanFacory接口
这个接口的就是为了方便通过上下文获取对应的bean
public interface BeanFactory { public Object getBean(String beanName); }
3.实现BeanFactory接口,读取配置文件,实现装配
注意:这里使用的是jdom读取解析xml文件的方式
关于读取解析xml文件的方式详见:http://dyygusi.iteye.com/blog/1996153
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; public class MyClassPathXMLApplicationContext implements BeanFactory { //所有被容器管理的bean都放在这个map中,当解析完xml以后,所有的bean都放在了这个集合中 private Map<String, Object> beans = new HashMap<String, Object>(); @SuppressWarnings("unchecked") public MyClassPathXMLApplicationContext(String xmlPath) { xmlPath = "E:\\XNYY\\webSpring_\\src\\" + xmlPath; SAXBuilder builder = new SAXBuilder(false);// 用来读取xml文件 Document document;// 构建一个文档对象,用来将xml转换成Document对象 try { document = builder.build(new FileInputStream(new File(xmlPath)));// 从给定的文件中读取xml并且构建成Document Element elementRoot = document.getRootElement();// 获得文档对象的根节点 List<Element> elementList = elementRoot.getChildren("bean");// 获得根节点下面所有的bean节点 for (Element e : elementList) {// 遍历bean节点 Element element = e;// 当前的bean节点 String id = element.getAttribute("id").getValue();// bean的id String clazzStr = element.getAttribute("class").getValue();// bena的class Class clazz = Class.forName(clazzStr);// 通过反射,得到bean的class的Class Object clazzObj = clazz.newInstance();// 获得一个class对应的实例 beans.put(id, clazzObj);// 将bean的id和class放入map集合中 List<Element> propertyElementList = element.getChildren("property");// 得到bean下所有的property元素 for (Element property : propertyElementList) {// 遍历所有的property元素节点 String name = property.getAttributeValue("name");// 得到property的name Object valueObj = null;// perperty的name对应的object Method[] methods = clazz.getMethods();// 得到class下所有的方法 // 如果需要注入的是基本类型包括String String valueStr = property.getAttributeValue("value"); if (valueStr != null) { valueObj = valueStr; for (Method method : methods) {// 遍历所有的方法 String methodName = method.getName();// 方法名称 Class[] types = method.getParameterTypes();// 方法参数类型 // 找到对应的setXxx方法 if (methodName.contains("set") && methodName.toUpperCase().contains(name.toUpperCase())) { Class parameterType = types[0];// 得到setXxx方法参数类型 // 如果是Integer类型 if (parameterType == Integer.class) { method.invoke(clazzObj, Integer.parseInt(valueStr)); } else {// 如果是String类型 method.invoke(clazzObj, valueStr); } } } } // 如果注入的是引用类型 String refStr = property.getAttributeValue("ref"); if (refStr != null) { valueObj = beans.get(refStr);// 在map中取出对应的引用对象 for (Method m : methods) { String methodName = m.getName(); if (methodName.contains("set") && methodName.toUpperCase().contains(name.toUpperCase())) { // 得到对应的方法,第二个参数是method方法的参数类型,是一个接口类型 Method method = clazz.getMethod(methodName, valueObj.getClass().getInterfaces()[0]); method.invoke(clazzObj, valueObj); } } } } } } catch (JDOMException | IOException | ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } } @Override public Object getBean(String beanName) { return beans.get(beanName); } }
4.测试MyClassPathXMLApplicationContext
@Test public void testMyApplication() { BeanFactory context = new MyClassPathXMLApplicationContext("My-application-context.xml");//初始化容器 UserService userService = (UserService) context.getBean("userService");//从容器里面得到UserService User user = (User) context.getBean("user");//得到User对象 userService.addUser(user);//通过Service将得到的User对象存入数据库 }
5.其他代码:
User.java(pojo)
UserDao.java(dao)
UserService.java(service)
相关推荐
NULL 博文链接:https://gaojiewyh.iteye.com/blog/409606
spring容器的触发事件 ClassPathXmlApplicationContext的start()方法的用法
手写SpringIoc的XML实现方式,仿照Spring底层Bean工厂类实现ClassPathXmlApplicationContext
6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.1.1. @Configurable object的单元测试 6.8.1.2. 多application context情况下的处理 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来...
NULL 博文链接:https://canfly2010.iteye.com/blog/443063
package com.ohc.spring; import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdom.Document; import org.jdom.Element; import org.jdom....
NULL 博文链接:https://cuiran.iteye.com/blog/487385
在Spring1.2或之前的版本中,实现AOP的传统方式就是通过实现Spring的AOP API来定义Advice,并设置代理对象。Spring根据Adivce加入到业务流程的时机的不同,提供了四种不同的Advice:Before Advice、After Advice、...
例子简单的实现了spring结合mongo的例子 spring:4.1.2 spring-data-mongodb:1.1.0 java:1.8 log4j:1.2.16 junit:4.12 commons-logging:1.1.1 maven:3 注意:spring的不同版本与mongodb结合可能会有问题,自测:...
在Java项目中,会通过ClassPathXmlApplicationContext类来实例化ApplicationContext容器。而在Web项目中,ApplicationContext容器的实例化工作会交由Web服务器来完成。 Web服务器实例化ApplicationContext容器时,...
spring读取配置不同目录下的配置文件,使用ClassPathXmlApplicationContext与FileSystemXmlApplicationContext
本例子用到Spring MVC , Jdbc, JSon, Gson 等等技术,Spring Servlet 配置,Spring中ClassPathXmlApplicationContext类的简单使用,Jdbc的配置与数据库的读取,List与json的转换,java对象使⽤Gson转json字符串null...
ClassPathXmlApplicationContext:使用这个工厂创建对象,他会根据scope智能判断是否懒加载,如果是单例则创建容器时就会创建里面bean的实例,如果是多例在获取使用时才会创建bean实例 ...
加载xml文件使用ClassPathXmlApplicationContext("applicationContext.xml") (3)BeanFactory(bean工厂)与ApplicationContext(容器)对比: 所有在xml里配置的Bean标签最后都会转换为BeanDefinition对象存放在...
* IOC:spring容器控制对象的生命周期:前提条件:在spring容器中的bean必须是单例的 * 创建 * 方式 * 利用默认的构造函数,如果没有默认的构造函数,会报错 * 利用静态工厂方法 * 利用实例工厂方法 * 时机 *...
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //输出spring容器 System.out.println(ctx); //打印加载的bean名称 System.out.println(java.util.Arrays....
mybatis实战教程mybatis in action之三实现数据的增删改查 mybatis实战教程mybatis in action之四实现关联数据的查询 mybatis实战教程mybatis in action之五与spring3集成附源码 mybatis实战教程mybatis in action之...
,以ClassPathXmlApplicationContext为例 ,以AnnotationConfigApplicationContext为例 学习Spring源码建议构建Spring-framemwork源码环境(这是一个比较麻烦的过程,可能遇到各种问题,需要有耐心..),新建一个...
ClassPathXmlApplicationContext ClassUtils CleanupFailureDataAccessException ClobStringType ClobStringType ClobStringTypeHandler CodebaseAwareObjectInputStream CollectionFactory CollectionUtils...