IOC实现练习

来源:互联网 发布:北上广深 知乎 编辑:程序博客网 时间:2024/06/08 16:20

学习java到一定程度基本都学过spring,它的核心IOC和AOP肯定少不了要了解一下。于是想自己实现一下,不一定和spring一样,但是多少可能会收到其思想影响。

首先在工程中建立一个xml配置文件和想要实例化的类,不考虑格式验证,简单一些如下:

<?xml version="1.0" encoding="UTF-8"?><beans><bean id="mybean" class="cion.bean.service.impl.ServiceImpl"></bean></beans>
public class ServiceImpl implements IService {public String process(String param) {System.out.println(this.getClass().getName() + " : " + param);return null;}}

首先考虑是解释该xml文件得到bean,并注入类的实例中。直接使用dom解释,建立一个工具类XMLUtil.java,简单封装解释方法:

private static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();public static Document parse(InputStream inputStream){try {Document doc = factory.newDocumentBuilder().parse(inputStream);return doc;} catch (SAXException | IOException | ParserConfigurationException e ) {e.printStackTrace();}return null;}

 对xml节点解释得到的是node对象,每一个node对应一个bean实例化需要的配置信息,考虑建立一个配置类BeanConfig,存储每一个node的信息,然后传递给bean工厂进行实例化:

public class BeanConfig {public final static String METHOD_PRE = "setBean";private String beanid;private String beanclass;public String getBeanid() {return beanid;}public void setBeanid(String beanid) {this.beanid = beanid;}public String getBeanclass() {return beanclass;}public void setBeanclass(String beanclass) {this.beanclass = beanclass;}}

在XMLUtil类中更加方法用于解释每个node节点,返回beanconfig集合,比较简单,忽略了一些检查:

public List<BeanConfig> parseBeans(String filename){InputStream is = XMLUtil.class.getClassLoader().getResourceAsStream(filename);assert is != null : filename + " not found!";Document doc = XMLUtil.parse(is);Element root = doc.getDocumentElement();NodeList nodes = root.getChildNodes();List<BeanConfig> beanconfigs = new ArrayList<BeanConfig>();if(nodes.getLength() > 0){for(int i=0; i<nodes.getLength(); i++){Node node = nodes.item(i);//获取节点NamedNodeMap attrMap = node.getAttributes();//获取节点属性if(attrMap != null && attrMap.getLength() > 0){BeanConfig beanconfig = new BeanConfig();for(int j=0; j<attrMap.getLength(); j++){Node item = attrMap.item(j);setAttr(beanconfig, item);}beanconfigs.add(beanconfig);}}}return beanconfigs;}private void setAttr(BeanConfig beanconfig, Node item){String methodname = BeanConfig.METHOD_PRE + item.getNodeName();Method method;try {method = beanconfig.getClass().getMethod(methodname, String.class);method.invoke(beanconfig, new Object[]{item.getNodeValue()});} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {e.printStackTrace();}}

考虑创建一个bean工厂,封装方法根据配置实例化bean:

public class BeanFactory {private static Map<String, Object> beans = new HashMap<String, Object>();private final static BeanFactory beanFactory = new BeanFactory();private BeanFactory(){}public static BeanFactory getInstance(){return beanFactory;}/** * 获取bean * @param name * @return */public static Object getBean(String name){return beans.get(name);} public void createBeans(List<BeanConfig> beanconfigs){assert beanconfigs != null;for(BeanConfig beanconfig : beanconfigs){try {Object object = Class.forName(beanconfig.getBeanclass()).newInstance();beans.put(beanconfig.getBeanid(), object);//还可以给bean注入更多属性和调用初始方法} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {e.printStackTrace();}}}}

测试一下:

public class App {    public static void main( String[] args ){    BeanFactory.getInstance().createBeans(new XMLUtil().parseBeans("config/bean.xml"));    IService service = (IService) BeanFactory.getBean("mybean");    service.process("test");    }}

输出结果为:
cion.bean.service.impl.ServiceImpl : test

 实例化工作完成,接下来进行注入,未完待续。。。