1、首先从简单使用开始
spring xml配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" > <bean id ="person" class="org.spring.Person"> <property name="name" value="zhangsan"></property> </bean> </beans>
java 代码:
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
测试代码:
ClassPathResource resource = new ClassPathResource("spring-ioc.xml"); DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); reader.loadBeanDefinitions(resource); Person person = beanFactory.getBean(Person.class); System.out.println(person);
运行结果:
=======================从源码层面简单分析一下逻辑===================
一个简单的Bean工厂实现有以下几个步骤:
- 步骤1:创建BeanFactory工厂类,用来缓存生成的BeanDefinition和bean实例
- 步骤2:创建XmlBeanDefinitionReader类,解析xml资源,创建Document对象
- 步骤3:创建BeanDefinitionDocumentReader类,解析Document对象
- 步骤4:创建BeanDefinitionParserDelegate类, 专门解析<bean>元素的Element对象以及自定义标签元素(例如:<dubbo:server> <dubbo:service>),自定义标签解析任务会委托给NamespaceHandler处理
- 步骤5: 创建NamespaceHandler类,处理自定义的命名空间;创建BeanDefinitionParser类,处理自定义的标签元素
===========根据上面步骤自己实现一版简化版的Bean工厂容器===================
准备阶段:
1、xml配置
<?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:dubbo="http://www.myspringtest.org/schema/dubbo/spring-dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.myspringtest.org/schema/dubbo/spring-dubbo http://www.myspringtest.org/schema/dubbo/spring-dubbo.xsd">
<bean id="person" class="org.spring.xml.bean.Person">
<property name="name" value="zhangsan"></property>
</bean>
<dubbo:server url="http://localhost" port="8080"></dubbo:server>
<dubbo:service serviceName="Login" methodName="auth"></dubbo:service>
</beans>
2、准备三个bean类
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Server {
private String url;
private String port;
public void setUrl(String url) {
this.url = url;
}
public void setPort(String port) {
this.port = port;
}
}
public class Service {
private String serviceName;
private String methodName;
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
}
编码阶段:
1、定义一个简化版的BeanDefinition,<bean>元素解析后的内容都被封装成BeanDefinition
public class BeanDefinition {
//装载bean的Class
private Class<?> beanClass;
//装载bean的属性名称和属性值,简单起见仅支持String类型字段
//在spring IOC中用MutablePropertyValues装载属性
private Map<String, Object> propertyValueMap = new HashMap<String, Object>(0);
public void setBeanClass(Class<?> beanClass) {
this.beanClass = beanClass;
}
public Class<?> getBeanClass() throws IllegalStateException {
return this.beanClass;
}
public void addPropertyValue(String name, Object value) {
propertyValueMap.put(name, value);
}
public Map<String, Object> getPropertyValueMap() {
return propertyValueMap;
}
}
2、便于程序处理,定义一个BeanDefinition携带者类==》BeanDefinitionHolder
public class BeanDefinitionHolder {
//装载bean的定义信息
private final BeanDefinition beanDefinition;
//bean的名称
private final String beanName;
public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName) {
this.beanDefinition = beanDefinition;
this.beanName = beanName;
}
public BeanDefinition getBeanDefinition() {
return beanDefinition;
}
public String getBeanName() {
return beanName;
}
}
3、定义一个BeanDefinitionRegistry接口,用于注册BeanDefinition
public interface BeanDefinitionRegistry {
//注册beanDefinition
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);
}
4、定义一个简单的Bean工厂类:SimpleBeanFactory,用来缓存BeanDefinition、创建Bean实例以及缓存生成的单例Bean实例
public class SimpleBeanFactory implements BeanDefinitionRegistry {
//用来缓存生成的beanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
//用来缓存生成的bean实例
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
//---------------------------------------------------------------------
// Implementation of BeanDefinitionRegistry interface
//---------------------------------------------------------------------
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
this.beanDefinitionMap.put(beanName, beanDefinition);
}
//获取bean对象,简单模拟创建bean的过程
public Object getBean(String beanName) {
if(singletonObjects.containsKey(beanName)) {
return singletonObjects.get(beanName);
} else {
if(beanDefinitionMap.containsKey(beanName)) {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
Class<?> beanClass = beanDefinition.getBeanClass();
try {
//实例化bean对象
O