forked from DerekYRC/mini-spring
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
275 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinitionReader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package org.springframework.beans.factory.support; | ||
|
||
import org.springframework.beans.BeansException; | ||
import org.springframework.core.io.DefaultResourceLoader; | ||
import org.springframework.core.io.Resource; | ||
import org.springframework.core.io.ResourceLoader; | ||
|
||
/** | ||
* @author derekyi | ||
* @date 2020/11/26 | ||
*/ | ||
public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader { | ||
|
||
private final BeanDefinitionRegistry registry; | ||
|
||
private ResourceLoader resourceLoader; | ||
|
||
protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) { | ||
this.registry = registry; | ||
this.resourceLoader = new DefaultResourceLoader(); | ||
} | ||
|
||
@Override | ||
public BeanDefinitionRegistry getRegistry() { | ||
return registry; | ||
} | ||
|
||
@Override | ||
public void loadBeanDefinitions(String[] locations) throws BeansException { | ||
for (String location : locations) { | ||
loadBeanDefinitions(location); | ||
} | ||
} | ||
|
||
public void setResourceLoader(ResourceLoader resourceLoader) { | ||
this.resourceLoader = resourceLoader; | ||
} | ||
|
||
@Override | ||
public ResourceLoader getResourceLoader() { | ||
return resourceLoader; | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
src/main/java/org/springframework/beans/factory/support/BeanDefinitionReader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package org.springframework.beans.factory.support; | ||
|
||
import cn.hutool.core.bean.BeanException; | ||
import org.springframework.beans.BeansException; | ||
import org.springframework.core.io.Resource; | ||
import org.springframework.core.io.ResourceLoader; | ||
|
||
/** | ||
* 读取bean定义信息即BeanDefinition的接口 | ||
* | ||
* @author derekyi | ||
* @date 2020/11/26 | ||
*/ | ||
public interface BeanDefinitionReader { | ||
|
||
BeanDefinitionRegistry getRegistry(); | ||
|
||
ResourceLoader getResourceLoader(); | ||
|
||
void loadBeanDefinitions(Resource resource) throws BeansException; | ||
|
||
void loadBeanDefinitions(String location) throws BeansException; | ||
|
||
void loadBeanDefinitions(String[] locations) throws BeansException; | ||
} |
106 changes: 106 additions & 0 deletions
106
src/main/java/org/springframework/beans/factory/xml/XmlBeanDefinitionReader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package org.springframework.beans.factory.xml; | ||
|
||
import cn.hutool.core.util.StrUtil; | ||
import cn.hutool.core.util.XmlUtil; | ||
import org.springframework.beans.BeansException; | ||
import org.springframework.beans.PropertyValue; | ||
import org.springframework.beans.factory.config.BeanDefinition; | ||
import org.springframework.beans.factory.config.BeanReference; | ||
import org.springframework.beans.factory.support.AbstractBeanDefinitionReader; | ||
import org.springframework.beans.factory.support.BeanDefinitionRegistry; | ||
import org.springframework.core.io.Resource; | ||
import org.springframework.core.io.ResourceLoader; | ||
import org.w3c.dom.Document; | ||
import org.w3c.dom.Element; | ||
import org.w3c.dom.NodeList; | ||
|
||
import java.io.InputStream; | ||
|
||
/** | ||
* 读取配置在xml文件中的bean定义信息 | ||
* | ||
* @author derekyi | ||
* @date 2020/11/26 | ||
*/ | ||
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { | ||
|
||
public static final String BEAN_ELEMENT = "bean"; | ||
public static final String PROPERTY_ELEMENT = "property"; | ||
public static final String ID_ATTRIBUTE = "id"; | ||
public static final String NAME_ATTRIBUTE = "name"; | ||
public static final String CLASS_ATTRIBUTE = "class"; | ||
public static final String VALUE_ATTRIBUTE = "value"; | ||
public static final String REF_ATTRIBUTE = "ref"; | ||
|
||
public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) { | ||
super(registry); | ||
} | ||
|
||
@Override | ||
public void loadBeanDefinitions(String location) throws BeansException { | ||
ResourceLoader resourceLoader = getResourceLoader(); | ||
Resource resource = resourceLoader.getResource(location); | ||
loadBeanDefinitions(resource); | ||
} | ||
|
||
@Override | ||
public void loadBeanDefinitions(Resource resource) throws BeansException { | ||
try { | ||
InputStream inputStream = resource.getInputStream(); | ||
try { | ||
doLoadBeanDefinitions(inputStream); | ||
} finally { | ||
inputStream.close(); | ||
} | ||
} catch (Exception ex) { | ||
throw new BeansException("IOException parsing XML document from " + resource, ex); | ||
} | ||
} | ||
|
||
protected void doLoadBeanDefinitions(InputStream inputStream) throws Exception { | ||
Document document = XmlUtil.readXML(inputStream); | ||
Element root = document.getDocumentElement(); | ||
NodeList childNodes = root.getChildNodes(); | ||
for (int i = 0; i < childNodes.getLength(); i++) { | ||
if (childNodes.item(i) instanceof Element) { | ||
if (BEAN_ELEMENT.equals(((Element) childNodes.item(i)).getNodeName())) { | ||
//解析bean标签 | ||
Element bean = (Element) childNodes.item(i); | ||
String id = bean.getAttribute(ID_ATTRIBUTE); | ||
String name = bean.getAttribute(NAME_ATTRIBUTE); | ||
String className = bean.getAttribute(CLASS_ATTRIBUTE); | ||
|
||
Class<?> clazz = Class.forName(className); | ||
//id优先于name | ||
String beanName = StrUtil.isNotEmpty(id) ? id : name; | ||
if (StrUtil.isEmpty(beanName)) { | ||
//如果id和name都为空,将类名的第一个字母转为小写后作为bean的名称 | ||
beanName = StrUtil.lowerFirst(clazz.getSimpleName()); | ||
} | ||
|
||
BeanDefinition beanDefinition = new BeanDefinition(clazz); | ||
|
||
for (int j = 0; j < bean.getChildNodes().getLength(); j++) { | ||
if (bean.getChildNodes().item(j) instanceof Element) { | ||
if (PROPERTY_ELEMENT.equals(((Element) bean.getChildNodes().item(j)).getNodeName())) { | ||
//解析property标签 | ||
Element property = (Element) bean.getChildNodes().item(j); | ||
String nameAttribute = property.getAttribute(NAME_ATTRIBUTE); | ||
String valueAttribute = property.getAttribute(VALUE_ATTRIBUTE); | ||
String refAttribute = property.getAttribute(REF_ATTRIBUTE); | ||
|
||
Object value = valueAttribute; | ||
if (StrUtil.isNotEmpty(refAttribute)) { | ||
value = new BeanReference(refAttribute); | ||
} | ||
PropertyValue propertyValue = new PropertyValue(nameAttribute, value); | ||
beanDefinition.getPropertyValues().addPropertyValue(propertyValue); | ||
} | ||
} | ||
} | ||
getRegistry().registerBeanDefinition(beanName, beanDefinition); | ||
} | ||
} | ||
} | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
src/test/java/org/springframework/test/ioc/XmlFileDefineBeanTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package org.springframework.test.ioc; | ||
|
||
import org.junit.Test; | ||
import org.springframework.beans.factory.support.DefaultListableBeanFactory; | ||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; | ||
import org.springframework.test.ioc.bean.Car; | ||
import org.springframework.test.ioc.bean.Person; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
/** | ||
* @author derekyi | ||
* @date 2020/11/26 | ||
*/ | ||
public class XmlFileDefineBeanTest { | ||
|
||
@Test | ||
public void testXmlFile() throws Exception { | ||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); | ||
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); | ||
beanDefinitionReader.loadBeanDefinitions("classpath:spring.xml"); | ||
|
||
Person person = (Person) beanFactory.getBean("person"); | ||
System.out.println(person); | ||
assertThat(person.getName()).isEqualTo("derek"); | ||
assertThat(person.getCar().getBrand()).isEqualTo("porsche"); | ||
|
||
Car car = (Car) beanFactory.getBean("car"); | ||
System.out.println(car); | ||
assertThat(car.getBrand()).isEqualTo("porsche"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<beans xmlns="http://www.springframework.org/schema/beans" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xmlns:context="http://www.springframework.org/schema/context" | ||
xsi:schemaLocation="http://www.springframework.org/schema/beans | ||
http://www.springframework.org/schema/beans/spring-beans.xsd | ||
http://www.springframework.org/schema/context | ||
http://www.springframework.org/schema/context/spring-context-4.0.xsd"> | ||
|
||
<bean id="person" class="org.springframework.test.ioc.bean.Person"> | ||
<property name="name" value="derek"/> | ||
<property name="car" ref="car"/> | ||
</bean> | ||
|
||
<bean id="car" class="org.springframework.test.ioc.bean.Car"> | ||
<property name="brand" value="porsche"/> | ||
</bean> | ||
|
||
</beans> |