package ioc; import java.io.File; 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 module.model.User; import module.service.UserService; import module.serviceImpl.UserServiceImpl; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; /** * 模拟spring框架中的 上下文类(必须实现beanFactory接口) * beanMap : 存放所有注入的bean;实例化该类的时候读取xml配置文件注入所有的bean; * @ClassName:ClassPathXmlApplicationContext.java * @Description: * @author:孙晓宁 * @date:2016-8-18上午11:22:16 */ public class ClassPathXmlApplicationContext implements BeanFactory{ //bean工厂的容器 private static Map<String, Object> beanMap = new HashMap<String, Object>(); /** * 构造函数 * @param xmlPath */ public ClassPathXmlApplicationContext(String xmlPath){ if(xmlPath == null){ initBeanMap(); }else{ //xmlPath = "WebRoot/userBean.xml"; initBeanMap(xmlPath); } } /** * 根据beanId获取该bean */ public Object getBeanById(String beanId){ Object beanObj = beanMap.get(beanId); System.out.println("<--取: "+beanId+"//"+beanObj); return beanObj; } /** * 填充beanMap-普通方式 * @methodName: initBeanMap * @description: * @param * @return void * @throws # @eg: */ private void initBeanMap(){ //注入userDao String userDaoImplPath = "module.daoImpl.UserDaoImpl"; String userDaoImplName = "UserDaoImpl"; try { Object userDaoImpl = Class.forName(userDaoImplPath).newInstance(); beanMap.put(userDaoImplName, userDaoImpl); System.out.println("-->注入:"+userDaoImpl); //存疑,当方法中的参数类别是接口时,怎么处理? /*String userDaoPath = "module.dao.UserDao"; String userDaoName = "UserDao"; Object userDao = Class.forName(userDaoPath).getComponentType(); beanMap.put(userDaoName, userDao); System.out.println("-->注入:"+userDao);*/ //2.1注入userService String userServiceImplPath = "module.serviceImpl.UserServiceImpl"; String userServiceId = "UserService"; Object userService = Class.forName(userServiceImplPath).newInstance(); System.out.println("-->注入:"+userService); beanMap.put("UserService", userService); //2.2为userService设定参数userdao - 这里应该注册userDao,写法上有别,下边读取xml时注意接口的注册写法 String mothdName = setMothd("userDao"); Method method = userService.getClass().getMethod(mothdName, getBeanById("UserDaoImpl").getClass()); method.invoke(userService, userDaoImpl); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 填充beanMap-模拟spring框架,读取spring.xml文件,注入bean,并且为某些bean注入参数 * //注意:构造函数中参数为接口时:getClass().getInterfaces()[0] * @methodName: initBeanMap * @description: * @param @param xmlPath * @return void * @throws # @eg: */ private void initBeanMap(String xmlPath){ // xml文档 // xmlPath = "WebRoot/userBean.xml"; System.out.println("****开始解析xml:"+xmlPath); File xmlFile = new File(xmlPath); //xml文档构造器 SAXBuilder builder = new SAXBuilder(); try { //生成文档 Document doc = builder.build(xmlFile); Element root = doc.getRootElement(); System.out.println("xml根:"+root); List<Element> childrenList = root.getChildren(); String beanId,beanPath; for (Element element : childrenList) { System.out.println("root的子元素:"+element); beanId = element.getAttributeValue("id"); beanPath = element.getAttributeValue("class"); System.err.println("##扫描到bean映射信息:"+beanId+"//"+beanPath); try { Object beanObj = Class.forName(beanPath).newInstance(); beanMap.put(beanId, beanObj); System.out.println("-->注入成功:"+beanId+"-->"+beanObj); List<Element> children2List = element.getChildren(); String paramName,paramValue; for (Element element2 : children2List) { System.out.println("为该bean注入参数:"+element2); paramName = element2.getAttribute("name").getValue(); paramValue = element2.getAttribute("value").getValue(); System.out.println("参数名/对应bean:"+paramName+"//"+paramValue); String mothdName = setMothd(paramName); //注意:构造函数中参数为接口时:getClass().getInterfaces()[0] Method m = beanObj.getClass().getMethod(mothdName,getBeanById(paramValue).getClass().getInterfaces()[0]); m.invoke(beanObj, getBeanById(paramValue)); } System.out.println(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); }catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } } } catch (JDOMException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * java类中set方法的生成原理 (首字母大写,最前面加上"set"): id -> setId * @methodName: setMothd * @description: * @param @param name * @param @return * @return String * @throws # @eg: */ public static String setMothd(String name) { String result = "set" + name.substring(0, 1).toUpperCase()+ name.substring(1); // setUserDao return result; } public static void main(String[] args) { User user = new User(); String xmlPath = "WebRoot/userBean.xml"; UserService userService = (UserService) new ClassPathXmlApplicationContext(xmlPath).getBeanById("UserService"); //验证反射生成的类是不是属于 Userservice boolean flg = userService instanceof UserServiceImpl; boolean flg2 = userService instanceof UserService; System.out.println("两个类是相同类型吗:"+flg); System.out.println("两个类2是相同类型吗:"+flg2); userService.addUser(user); } }

2636804923 LV6
2024年6月17日
fuyouou LV5
2023年7月7日
我睡觉时不困 LV7
2022年11月13日
快来救救胡桃 LV6
2022年1月6日
jwfadacai LV8
2022年1月4日
jimshao289015254 LV9
2022年1月3日
懒得起 LV8
2020年8月31日
liuwenlong LV20
2019年12月28日
13734993 LV7
2019年8月7日
freedom2017 LV14
2019年7月17日

2636804923 LV6
2024年6月16日
fuyouou LV5
2023年7月7日
xuthus LV1
2023年6月29日
GGadmin
2023年2月3日
暂无贡献等级
我睡觉时不困 LV7
2022年11月13日
QQ353251504
2022年2月24日
暂无贡献等级
快来救救胡桃 LV6
2022年1月6日
cuberbread LV6
2022年1月6日
jwfadacai LV8
2022年1月4日
jimshao289015254 LV9
2021年12月31日