首页>代码>自己手动模拟spring框架的IOC(依赖注入,DI,控制反转)>/spring3.0-IOC/src/ioc/ClassPathXmlApplicationContext.java
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);
	}
}
最近下载更多
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日
Justnoolb  LV1 2019年6月27日
最近浏览更多
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日
WYH1346 2021年6月12日
暂无贡献等级
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友