通过tiny-spring学习Spring框架源码(一)

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();

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值