├── .classpath ├── .project ├── README.md ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── lc │ │ ├── Resource │ │ ├── tinyioc.xml │ │ └── tinyioc.xml.bak │ │ └── spring │ │ ├── bean │ │ ├── AbstractBeanDefinitionReader.java │ │ ├── BeanDefinition.java │ │ ├── BeanDefinitionReader.java │ │ ├── BeanReference.java │ │ ├── PropertyValue.java │ │ └── PropertyValues.java │ │ ├── context │ │ ├── AbstractApplicationContext.java │ │ ├── ApplicationContext.java │ │ └── ClassPathXmlApplicationContext.java │ │ ├── factory │ │ ├── AbstractBeanFactory.java │ │ ├── AutoWireCapableBeanFactory.java │ │ └── BeanFactory.java │ │ ├── io │ │ ├── Resource.java │ │ ├── ResourceLoader.java │ │ └── UrlResource.java │ │ └── xml │ │ └── XmlBeanDefinitionReader.java └── webapp │ ├── WEB-INF │ └── web.xml │ └── index.jsp └── test ├── java ├── ApplicationContextTest.java ├── BeanFactoryTest.java ├── HelloWorldService.java ├── OutputService.java ├── XmlTest.java ├── io │ └── ResourceLoaderTest.java └── xml │ └── XmlBeanDefinitionReaderTest.java └── resources └── tinyioc.xml /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | MyIoC 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MyIoC 2 | 模仿实现Spring的IoC容器 3 | 4 | # 项目整体架构图 5 | ![image](https://i.loli.net/2018/02/14/5a8453341295b.jpg) 6 | 7 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.lc 5 | MyIoC 6 | war 7 | 0.0.1-SNAPSHOT 8 | MyIoC Maven Webapp 9 | http://maven.apache.org 10 | 11 | 12 | junit 13 | junit 14 | 3.8.1 15 | test 16 | 17 | 18 | 19 | 20 | org.springframework 21 | spring-beans 22 | 4.2.2.RELEASE 23 | 24 | 25 | 26 | org.springframework 27 | spring-core 28 | 4.2.2.RELEASE 29 | 30 | 31 | 32 | org.springframework 33 | spring-context 34 | 4.2.2.RELEASE 35 | 36 | 37 | 38 | org.springframework 39 | spring-web 40 | 4.2.2.RELEASE 41 | 42 | 43 | 44 | org.springframework 45 | spring-jdbc 46 | 4.2.2.RELEASE 47 | 48 | 49 | 50 | org.springframework 51 | spring-aop 52 | 4.2.2.RELEASE 53 | 54 | 55 | 56 | 57 | org.springframework 58 | spring-aspects 59 | 4.2.2.RELEASE 60 | 61 | 62 | 63 | 64 | MyIoC 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/main/java/com/lc/Resource/tinyioc.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/main/java/com/lc/Resource/tinyioc.xml.bak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoldenLiang/MyIoC/4b415f423a26f24fc19a91470ba4552b9570d978/src/main/java/com/lc/Resource/tinyioc.xml.bak -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/bean/AbstractBeanDefinitionReader.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.bean; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import com.lc.spring.io.ResourceLoader; 7 | 8 | /** 9 | * @author lc 10 | * 从配置中读取BeanDefinition 11 | */ 12 | public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader { 13 | 14 | private Map registry; 15 | 16 | private ResourceLoader resourceLoader; 17 | 18 | protected AbstractBeanDefinitionReader(ResourceLoader resourceLoader) { 19 | this.registry = new HashMap(); 20 | this.resourceLoader = resourceLoader; 21 | } 22 | 23 | public Map getRegistry() { 24 | return registry; 25 | } 26 | 27 | public ResourceLoader getResourceLoder() { 28 | return resourceLoader; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/bean/BeanDefinition.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.bean; 2 | 3 | /** 4 | * IoC容器内部的数据结构,用来封装Bean 对象 5 | * @author lc 6 | * 7 | */ 8 | public class BeanDefinition { 9 | 10 | private Object bean; 11 | 12 | private Class beanClass; 13 | 14 | private String beanClassName; 15 | 16 | private PropertyValues propertyValues = new PropertyValues(); 17 | 18 | public BeanDefinition() { 19 | 20 | } 21 | 22 | public Class getBeanClass() { 23 | return beanClass; 24 | } 25 | 26 | public void setBeanClass(Class beanClass) { 27 | this.beanClass = beanClass; 28 | } 29 | 30 | public String getBeanClassName() { 31 | return beanClassName; 32 | } 33 | 34 | public void setBeanClassName(String beanClassName) { 35 | this.beanClassName = beanClassName; 36 | try { 37 | this.beanClass = Class.forName(beanClassName); 38 | } catch (ClassNotFoundException e) { 39 | e.printStackTrace(); 40 | } 41 | } 42 | 43 | public void setBean(Object bean) { 44 | this.bean = bean; 45 | } 46 | 47 | public Object getBean() { 48 | return bean; 49 | } 50 | 51 | public PropertyValues getPropertyValues() { 52 | return propertyValues; 53 | } 54 | 55 | public void setPropertyValues(PropertyValues propertyValues) { 56 | this.propertyValues = propertyValues; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/bean/BeanDefinitionReader.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.bean; 2 | 3 | public interface BeanDefinitionReader { 4 | 5 | void loadBeanDefinitions(String location) throws Exception; 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/bean/BeanReference.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.bean; 2 | 3 | 4 | /** 5 | * @author lc 6 | * 对另一个bean 的引用 7 | */ 8 | public class BeanReference { 9 | 10 | private String name; 11 | 12 | private Object bean; 13 | 14 | public BeanReference(String name) { 15 | this.name = name; 16 | } 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | public void setName(String name) { 22 | this.name = name; 23 | } 24 | 25 | public Object getBean() { 26 | return bean; 27 | } 28 | 29 | public void setBean(Object bean) { 30 | this.bean = bean; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/bean/PropertyValue.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.bean; 2 | 3 | 4 | /** 5 | * @author lc 6 | * 用于bean的属性注入 7 | */ 8 | public class PropertyValue { 9 | 10 | private final String name; 11 | 12 | private final Object value; 13 | 14 | public PropertyValue(String name, Object value) { 15 | this.name = name; 16 | this.value = value; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public Object getValue() { 24 | return value; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/bean/PropertyValues.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.bean; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author lc 8 | * 包装一个对象的所有PropertyValue 9 | * 使用封装而不直接用List 的原因?可以封装一些操作 10 | */ 11 | public class PropertyValues { 12 | 13 | private final List propertyValueList = new ArrayList(); 14 | 15 | public PropertyValues() { 16 | 17 | } 18 | 19 | public void addPropertyValue(PropertyValue pv) { 20 | //这里可以对重复PropertyName 进行判断,直接使用List 做不到 21 | this.propertyValueList.add(pv); 22 | } 23 | 24 | public List getPropertyValueList() { 25 | return this.propertyValueList; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/context/AbstractApplicationContext.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.context; 2 | 3 | import com.lc.spring.factory.AbstractBeanFactory; 4 | 5 | /** 6 | * @author lc 7 | * 用来实现 从不同来源的不同类型的资源加载类定义 的效果 8 | */ 9 | public abstract class AbstractApplicationContext implements ApplicationContext { 10 | 11 | protected AbstractBeanFactory beanFactory; 12 | 13 | public AbstractApplicationContext(AbstractBeanFactory beanFactory) { 14 | this.beanFactory = beanFactory; 15 | } 16 | 17 | public void refresh() throws Exception { 18 | 19 | } 20 | 21 | public Object getBean(String name) throws Exception { 22 | return beanFactory.getBean(name); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/context/ApplicationContext.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.context; 2 | 3 | import com.lc.spring.factory.BeanFactory; 4 | 5 | public interface ApplicationContext extends BeanFactory { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/context/ClassPathXmlApplicationContext.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.context; 2 | 3 | import java.util.Map; 4 | 5 | import com.lc.spring.bean.BeanDefinition; 6 | import com.lc.spring.factory.AbstractBeanFactory; 7 | import com.lc.spring.factory.AutoWireCapableBeanFactory; 8 | import com.lc.spring.io.ResourceLoader; 9 | import com.lc.spring.xml.XmlBeanDefinitionReader; 10 | 11 | public class ClassPathXmlApplicationContext extends AbstractApplicationContext { 12 | 13 | private String configLocation; 14 | 15 | public ClassPathXmlApplicationContext(String configLocation) throws Exception { 16 | this(configLocation, new AutoWireCapableBeanFactory()); 17 | } 18 | 19 | public ClassPathXmlApplicationContext(String configLocation, 20 | AbstractBeanFactory beanFactory) throws Exception { 21 | super(beanFactory); 22 | this.configLocation = configLocation; 23 | refresh(); 24 | } 25 | 26 | public void refresh(String name, BeanDefinition beanDefinition) throws Exception { 27 | XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(new ResourceLoader()); 28 | xmlBeanDefinitionReader.loadBeanDefinitions(configLocation); 29 | for (Map.Entry entry : xmlBeanDefinitionReader.getRegistry().entrySet()) { 30 | beanFactory.registerBeanDefinition(entry.getKey(), entry.getValue()); 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/factory/AbstractBeanFactory.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.factory; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | 9 | import com.lc.spring.bean.BeanDefinition; 10 | 11 | public abstract class AbstractBeanFactory implements BeanFactory{ 12 | 13 | private Map beanDefinitionMap = new ConcurrentHashMap(); 14 | 15 | private final List beanDefinitionNames = new ArrayList(); 16 | 17 | public Object getBean(String name) throws Exception { 18 | BeanDefinition beanDefinition = beanDefinitionMap.get(name); 19 | if(beanDefinition == null) { 20 | throw new IllegalArgumentException("No bean name [" + name + "] is defined"); 21 | } 22 | Object bean = beanDefinition.getBean(); 23 | if (bean == null) { 24 | bean = doCreateBean(beanDefinition); 25 | } 26 | return bean; 27 | } 28 | 29 | public void registerBeanDefinition(String name, BeanDefinition beanDefinition) throws Exception { 30 | beanDefinitionMap.put(name, beanDefinition); 31 | beanDefinitionNames.add(name); 32 | } 33 | 34 | public void preInstantiateSingletons() throws Exception { 35 | for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();) { 36 | String beanName = (String) it.next(); 37 | getBean(beanName); 38 | } 39 | } 40 | 41 | /** 42 | * 初始化Bean 43 | * @param beanDefinition 44 | * @return 45 | */ 46 | protected abstract Object doCreateBean(BeanDefinition beanDefinition) throws Exception; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/factory/AutoWireCapableBeanFactory.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.factory; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import com.lc.spring.bean.BeanDefinition; 6 | import com.lc.spring.bean.BeanReference; 7 | import com.lc.spring.bean.PropertyValue; 8 | 9 | public class AutoWireCapableBeanFactory extends AbstractBeanFactory { 10 | 11 | @Override 12 | protected Object doCreateBean(BeanDefinition beanDefinition) throws Exception { 13 | Object bean = createBeanInstance(beanDefinition); 14 | beanDefinition.setBean(bean); 15 | applyPropertyValues(bean, beanDefinition); 16 | return bean; 17 | } 18 | 19 | protected Object createBeanInstance(BeanDefinition beanDefinition) throws Exception { 20 | return beanDefinition.getBeanClass().newInstance(); 21 | } 22 | 23 | //使用Field 的形式注入,Spring本身使用setter 24 | protected void applyPropertyValues(Object bean, BeanDefinition mbd) throws Exception { 25 | for(PropertyValue propertyValue : mbd.getPropertyValues().getPropertyValueList()) { 26 | Field declaredField = bean.getClass().getDeclaredField(propertyValue.getName()); 27 | declaredField.setAccessible(true); 28 | Object value = propertyValue.getValue(); 29 | if(value instanceof BeanReference) { 30 | BeanReference beanReference = (BeanReference) value; 31 | value = getBean(beanReference.getName()); 32 | } 33 | declaredField.set(bean, value); 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/factory/BeanFactory.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.factory; 2 | 3 | /** 4 | * 使用HashMap 存储和维护BeanDefinition 5 | * @author lc 6 | */ 7 | public interface BeanFactory { 8 | 9 | public Object getBean(String name) throws Exception; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/io/Resource.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.io; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | /** 7 | * @author lc 8 | * Resource 是Spring 内部定位资源的接口 9 | */ 10 | public interface Resource { 11 | 12 | InputStream getInputStream() throws IOException; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/io/ResourceLoader.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.io; 2 | 3 | import java.net.URL; 4 | 5 | public class ResourceLoader { 6 | 7 | public Resource getResource(String location) { 8 | URL resource = this.getClass().getClassLoader().getResource(location); 9 | return new UrlResource(resource); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/io/UrlResource.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.io; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.net.URL; 6 | import java.net.URLConnection; 7 | 8 | public class UrlResource implements Resource { 9 | 10 | private final URL url; 11 | 12 | public UrlResource(URL url) { 13 | this.url = url; 14 | } 15 | 16 | public InputStream getInputStream() throws IOException { 17 | URLConnection urlConnection = url.openConnection(); 18 | urlConnection.connect(); 19 | return urlConnection.getInputStream(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/lc/spring/xml/XmlBeanDefinitionReader.java: -------------------------------------------------------------------------------- 1 | package com.lc.spring.xml; 2 | 3 | import java.io.InputStream; 4 | 5 | import javax.xml.parsers.DocumentBuilder; 6 | import javax.xml.parsers.DocumentBuilderFactory; 7 | import javax.xml.parsers.ParserConfigurationException; 8 | 9 | import org.w3c.dom.Document; 10 | import org.w3c.dom.Element; 11 | import org.w3c.dom.Node; 12 | import org.w3c.dom.NodeList; 13 | 14 | import com.lc.spring.bean.AbstractBeanDefinitionReader; 15 | import com.lc.spring.bean.BeanDefinition; 16 | import com.lc.spring.bean.BeanReference; 17 | import com.lc.spring.bean.PropertyValue; 18 | import com.lc.spring.io.ResourceLoader; 19 | 20 | /** 21 | * @author lc 22 | * 读取并解析xml 文件 23 | */ 24 | public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { 25 | 26 | public XmlBeanDefinitionReader(ResourceLoader resourceLoader) { 27 | super(resourceLoader); 28 | } 29 | 30 | public void loadBeanDefinitions(String location) throws Exception { 31 | InputStream inputStream = getResourceLoder().getResource(location).getInputStream(); 32 | doLoadBeanDefinitions(inputStream); 33 | } 34 | 35 | private void doLoadBeanDefinitions(InputStream inputStream) throws Exception { 36 | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 37 | DocumentBuilder docBuilder = factory.newDocumentBuilder(); 38 | Document doc = docBuilder.parse(inputStream); 39 | //解析bean 40 | registerBeanDefinitions(doc); 41 | inputStream.close(); 42 | } 43 | 44 | public void registerBeanDefinitions(Document doc) { 45 | Element root = doc.getDocumentElement(); 46 | 47 | parseBeanDefinition(root); 48 | } 49 | 50 | protected void parseBeanDefinition(Element root) { 51 | NodeList nl = root.getChildNodes(); 52 | for (int i = 0; i < nl.getLength(); i++) { 53 | Node node = nl.item(i); 54 | if (node instanceof Element) { 55 | Element ele = (Element) node; 56 | processBeanDefinition(ele); 57 | } 58 | } 59 | } 60 | 61 | //解析bean 标签 62 | protected void processBeanDefinition(Element ele) { 63 | String name = ele.getAttribute("name"); 64 | String className = ele.getAttribute("class"); 65 | 66 | BeanDefinition beanDefinition = new BeanDefinition(); 67 | processProperty(ele, beanDefinition); 68 | beanDefinition.setBeanClassName(className); 69 | 70 | getRegistry().put(name, beanDefinition); 71 | } 72 | 73 | //解析bean的子标签property 标签 74 | private void processProperty(Element ele, BeanDefinition beanDefinition) { 75 | NodeList propertyNode = ele.getElementsByTagName("property"); 76 | for (int i = 0; i < propertyNode.getLength(); i++) { 77 | Node node = propertyNode.item(i); 78 | if(node instanceof Element) { 79 | Element propertyEle = (Element) node; 80 | String name = propertyEle.getAttribute("name"); 81 | String value = propertyEle.getAttribute("value"); 82 | 83 | if (value != null && value.length() > 0) { 84 | beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue(name, value)); 85 | } else { 86 | String ref = propertyEle.getAttribute("ref"); 87 | if (ref == null || ref.length() == 0) { 88 | throw new IllegalArgumentException("Configuration problem : element for property" 89 | + name + "must specify a ref or value"); 90 | } 91 | BeanReference beanReference = new BeanReference(ref); 92 | beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue(name, beanReference)); 93 | } 94 | } 95 | } 96 | } 97 | 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | Archetype Created Web Application 7 | 8 | -------------------------------------------------------------------------------- /src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Hello World!

4 | 5 | 6 | -------------------------------------------------------------------------------- /src/test/java/ApplicationContextTest.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | import org.junit.Test; 4 | 5 | import com.lc.spring.context.ApplicationContext; 6 | import com.lc.spring.context.ClassPathXmlApplicationContext; 7 | 8 | public class ApplicationContextTest { 9 | 10 | @Test 11 | public void test() throws Exception { 12 | ApplicationContext applicationContext = new ClassPathXmlApplicationContext("tinyioc.xml"); 13 | HelloWorldService helloWorldService = (HelloWorldService) applicationContext.getBean("helloWorldService"); 14 | helloWorldService.helloWorld(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/BeanFactoryTest.java: -------------------------------------------------------------------------------- 1 | import java.util.Map; 2 | 3 | import org.junit.Test; 4 | 5 | import com.lc.spring.bean.BeanDefinition; 6 | import com.lc.spring.bean.PropertyValue; 7 | import com.lc.spring.bean.PropertyValues; 8 | import com.lc.spring.factory.AbstractBeanFactory; 9 | import com.lc.spring.factory.AutoWireCapableBeanFactory; 10 | import com.lc.spring.factory.BeanFactory; 11 | import com.lc.spring.io.ResourceLoader; 12 | import com.lc.spring.xml.XmlBeanDefinitionReader; 13 | 14 | public class BeanFactoryTest { 15 | 16 | @Test 17 | public void test() throws Exception { 18 | //1.初始化BeanDefinition 19 | BeanFactory beanFactory = new AutoWireCapableBeanFactory(); 20 | 21 | //2.bean定义 22 | BeanDefinition beanDefinition = new BeanDefinition(); 23 | beanDefinition.setBeanClassName("HelloWorldService"); 24 | 25 | //3.设置属性 26 | PropertyValues propertyValues = new PropertyValues(); 27 | propertyValues.addPropertyValue(new PropertyValue("text", "Hello IoC")); 28 | beanDefinition.setPropertyValues(propertyValues); 29 | 30 | //4.生成bean 31 | beanFactory.registerBeanDefinition("helloWorldService", beanDefinition); 32 | 33 | //5.获取bean 34 | HelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService"); 35 | helloWorldService.helloWorld(); 36 | } 37 | 38 | @Test 39 | public void testLazy() throws Exception { 40 | //1.读取配置 41 | XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(new ResourceLoader()); 42 | xmlBeanDefinitionReader.loadBeanDefinitions("tinyioc.xml"); 43 | 44 | //2.初始化BeanFactory 并注册bean 45 | AbstractBeanFactory beanFactory = new AutoWireCapableBeanFactory(); 46 | for (Map.Entry entry : xmlBeanDefinitionReader.getRegistry().entrySet()) { 47 | beanFactory.registerBeanDefinition(entry.getKey(), entry.getValue()); 48 | } 49 | 50 | //3.获取bean 51 | HelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService"); 52 | helloWorldService.helloWorld(); 53 | } 54 | 55 | @Test 56 | public void testPreInstantitate() throws Exception { 57 | //1.读取配置 58 | XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(new ResourceLoader()); 59 | xmlBeanDefinitionReader.loadBeanDefinitions("tinyioc.xml"); 60 | 61 | //2.初始化BeanFactory 并注册bean 62 | AbstractBeanFactory beanFactory = new AutoWireCapableBeanFactory(); 63 | for (Map.Entry entry : xmlBeanDefinitionReader.getRegistry().entrySet()) { 64 | beanFactory.registerBeanDefinition(entry.getKey(), entry.getValue()); 65 | } 66 | 67 | //3.初始化bean 68 | beanFactory.preInstantiateSingletons(); 69 | 70 | //4.获取bean 71 | HelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService"); 72 | helloWorldService.helloWorld(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/test/java/HelloWorldService.java: -------------------------------------------------------------------------------- 1 | 2 | public class HelloWorldService { 3 | 4 | private String text; 5 | 6 | private OutputService outputService; 7 | 8 | public void helloWorld() { 9 | System.out.println(text); 10 | } 11 | 12 | public void setText(String text) { 13 | this.text = text; 14 | } 15 | 16 | public void setOutputService(OutputService outputService) { 17 | this.outputService = outputService; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/OutputService.java: -------------------------------------------------------------------------------- 1 | import junit.framework.Assert; 2 | 3 | public class OutputService { 4 | 5 | private HelloWorldService helloWorldService; 6 | 7 | public void output(String text) { 8 | Assert.assertNotNull(helloWorldService); 9 | System.out.println(text); 10 | } 11 | 12 | public void setHelloWorldService(HelloWorldService helloWorldService) { 13 | this.helloWorldService = helloWorldService; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/XmlTest.java: -------------------------------------------------------------------------------- 1 | import java.util.Map; 2 | 3 | import org.junit.Test; 4 | 5 | import com.lc.spring.bean.BeanDefinition; 6 | import com.lc.spring.factory.AutoWireCapableBeanFactory; 7 | import com.lc.spring.factory.BeanFactory; 8 | import com.lc.spring.io.ResourceLoader; 9 | import com.lc.spring.xml.XmlBeanDefinitionReader; 10 | 11 | public class XmlTest { 12 | 13 | @Test 14 | public void test() throws Exception { 15 | //1.读取配置 16 | XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(new ResourceLoader()); 17 | xmlBeanDefinitionReader.loadBeanDefinitions("tinyioc.xml"); 18 | 19 | //2. 20 | BeanFactory beanFactory = new AutoWireCapableBeanFactory(); 21 | for(Map.Entry entry : xmlBeanDefinitionReader.getRegistry().entrySet()) { 22 | beanFactory.registerBeanDefinition(entry.getKey(), entry.getValue()); 23 | } 24 | 25 | //3. 26 | HelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService"); 27 | helloWorldService.helloWorld(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/io/ResourceLoaderTest.java: -------------------------------------------------------------------------------- 1 | package io; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | import org.junit.Assert; 7 | import org.junit.Test; 8 | 9 | import com.lc.spring.io.Resource; 10 | import com.lc.spring.io.ResourceLoader; 11 | 12 | public class ResourceLoaderTest { 13 | 14 | @Test 15 | public void test() throws IOException { 16 | ResourceLoader resourceLoader = new ResourceLoader(); 17 | Resource resource = resourceLoader.getResource("tinyioc.xml"); 18 | InputStream inputStream = resource.getInputStream(); 19 | Assert.assertNotNull(inputStream); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/xml/XmlBeanDefinitionReaderTest.java: -------------------------------------------------------------------------------- 1 | package xml; 2 | 3 | import java.util.Map; 4 | 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | import com.lc.spring.bean.BeanDefinition; 9 | import com.lc.spring.io.ResourceLoader; 10 | import com.lc.spring.xml.XmlBeanDefinitionReader; 11 | 12 | public class XmlBeanDefinitionReaderTest { 13 | 14 | @Test 15 | public void test() throws Exception { 16 | XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(new ResourceLoader()); 17 | xmlBeanDefinitionReader.loadBeanDefinitions("tinyioc.xml"); 18 | Map registry = xmlBeanDefinitionReader.getRegistry(); 19 | Assert.assertTrue(registry.size() > 0); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/resources/tinyioc.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | --------------------------------------------------------------------------------