Spring框架作为使用最多最广泛的Java框架,直接看源码的话,设计层级复杂,容易陷入其中,摸不清框架思路,艺华大神的tiny-spring通过庖丁解牛抽取Spring精华,一步一步拆解非常好的展现框架设计很好的思路,分为三篇来跟着艺华大神去体会这个经典框架的设计:
一、IOC容器
1、最基本的容器
- BeanDefinition保存bean配置信息
-
容器beanFactory对bean进行管理
定义bean对象及获取方法getBean
public class BeanDefinition {
private Object bean;
public BeanDefinition(Object bean) {
this.bean = bean;
}
public Object getBean() {
return bean;
}
}
定义bean工厂
public class BeanFactoryTest { @Test public void test() { // 1.初始化beanfactory BeanFactory beanFactory = new BeanFactory(); // 2.注入bean BeanDefinition beanDefinition = new BeanDefinition(new HelloWorldService()); beanFactory.registerBeanDefinition("helloWorldService", beanDefinition); // 3.获取bean HelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService"); helloWorldService.helloWorld(); } }
public class BeanFactory { private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(); public Object getBean(String name) { return beanDefinitionMap.get(name).getBean(); } public void registerBeanDefinition(String name, BeanDefinition beanDefinition) { beanDefinitionMap.put(name, beanDefinition); } }
测试bean的注入和获取方法
public class BeanFactoryTest {
@Test
public void test() {
// 1.初始化beanfactory
BeanFactory beanFactory = new BeanFactory();
// 2.注入bean
BeanDefinition beanDefinition = new BeanDefinition(new HelloWorldService());
beanFactory.registerBeanDefinition("helloWorldService", beanDefinition);
// 3.获取bean
HelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService");
helloWorldService.helloWorld();
}
}
2、将bean放入工厂来管理bean生命周期
- 抽象BeanFactory面向接口更易扩展-使用工厂模式将BeanFactory作为接口(遵循-开闭原则)
- 抽象的AbstractFactory内部初始化和注册bean
定义BeanFactory接口
public interface BeanFactory { Object getBean(String name); void registerBeanDefinition(String name, BeanDefinition beanDefinition); }
用抽象类实现Bean工厂,并定义抽象类
public abstract class AbstractBeanFactory implements BeanFactory { private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(); @Override public Object getBean(String name) { return beanDefinitionMap.get(name).getBean(); } @Override public void registerBeanDefinition(String name, BeanDefinition beanDefinition) { Object bean = doCreateBean(beanDefinition); beanDefinition.setBean(bean); beanDefinitionMap.put(name, beanDefinition); } /** * 初始化bean * @param beanDefinition * @return */ protected abstract Object doCreateBean(BeanDefinition beanDefinition); }
实现bean初始化
public class AutowireCapableBeanFactory extends AbstractBeanFactory { @Override protected Object doCreateBean(BeanDefinition beanDefinition) { try { Object bean = beanDefinition.getBeanClass().newInstance(); return bean; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } }
测试
public class BeanFactoryTest { @Test public void test() { // 1.初始化beanfactory BeanFactory beanFactory = new AutowireCapableBeanFactory(); // 2.注入bean BeanDefinition beanDefinition = new BeanDefinition(); beanDefinition.setBeanClassName("us.codecraft.tinyioc.HelloWorldService"); beanFactory.registerBeanDefinition("helloWorldService", beanDefinition); // 3.获取bean HelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService"); helloWorldService.helloWorld(); } }
3、为Bean注入属性
- PropertyValues:保存属性注入信息
- AutowireCapableBeanFactory:可自动装配的BeanFactory
public class PropertyValue { private final String name; private final Object value; public PropertyValue(String name, Object value) { this.name = name; this.value = value; } public String getName() { return name; } public Object getValue() { return value;
public class PropertyValues { private final List<PropertyValue> propertyValueList = new ArrayList<PropertyValue>(); public PropertyValues() { } public void addPropertyValue(PropertyValue pv) { //TODO:这里可以对于重复propertyName进行判断,直接用list没法做到 this.propertyValueList.add(pv); } public List<PropertyValue> getPropertyValues() { return this.propertyValueList; } }
}}定义bean属性的添加和获取方法
用反射将BeanDefinition中定义的字段注入进bean对象中
public class AutowireCapableBeanFactory extends AbstractBeanFactory { @Override protected Object doCreateBean(BeanDefinition beanDefinition) throws Exception { Object bean = createBeanInstance(beanDefinition); applyPropertyValues(bean, beanDefinition); return bean; } protected Object createBeanInstance(BeanDefinition beanDefinition) throws Exception { return beanDefinition.getBeanClass().newInstance(); } protected void applyPropertyValues(Object bean, BeanDefinition mbd) throws Exception { for (PropertyValue propertyValue : mbd.getPropertyValues().getPropertyValues()) { Field declaredField = bean.getClass().getDeclaredField(propertyValue.getName()); declaredField.setAccessible(true); declaredField.set(bean, propertyValue.getValue()); } } }
@Test public void test() throws Exception { // 1.初始化beanfactory BeanFactory beanFactory = new AutowireCapableBeanFactory(); // 2.bean定义 BeanDefinition beanDefinition = new BeanDefinition(); beanDefinition.setBeanClassName("us.codecraft.tinyioc.HelloWorldService"); // 3.设置属性 PropertyValues propertyValues = new PropertyValues(); propertyValues.addPropertyValue(new PropertyValue("text", "Hello World!")); beanDefinition.setPropertyValues(propertyValues); // 4.生成bean beanFactory.registerBeanDefinition("helloWorldService", beanDefinition); // 5.获取bean HelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService"); helloWorldService.helloWorld(); }