源码参考:github上的code4craft/tiny-spring
项目。
tiny-spring-step-3-inject-bean-with-property
文章目录
源码解析
BeanDefinition
BeanDefinition中存储了bean,className,properties元数据
PropertyValues
PropertyValues中保存的是bean的字段和值组成的list集合
PropertyValue
PropertyValue保存字段和属性值
BeanFactory
工厂提供注册和获取bean的方法。将工厂抽象成接口。
AbstractBeanFactory
AbstractBeanFactory实现了BeanFactory接口,重写了基本的注册和获取bean方法,同时提供初始化抽象方法doCreateBean()。
为什么要添加初始化方法?
因为在beanDefinition注册bean时,需要一个对象,这时候我们需要容器来自动创建,而不是我们手动创建一个对象来注册。
@Override
public void registerBeanDefinition(String name, BeanDefinition beanDefinition) {
Object bean = doCreateBean(beanDefinition);
beanDefinition.setBean(bean);
beanDefinitionMap.put(name, beanDefinition);
}
AutowireCapableBeanFactory
AutowireCapableBeanFactory(可自动装配的),继承了AbstractBeanFactory抽象类,实现了doCreateBean()方法。
public class AutowireCapableBeanFactory extends AbstractBeanFactory {
@Override
protected Object doCreateBean(BeanDefinition beanDefinition) throws Exception {
Object bean = createBeanInstance(beanDefinition);
applyPropertyValues(bean, beanDefinition);
return bean;
}
//自动装配。自动装配就是Spring会在上下文中自动查找,并自动给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());
}
}
}
测试
定义一个bean,取名为HelloWorldService
public class HelloWorldService {
private String text;
public void helloWorld(){
System.out.println(text);
}
public void setText(String text) {
this.text = text;
}
}
1.创建beanFactory
2.创建beanDefinition,对应的beanClassName为helloWorldService 的全类名
3.设置属性值
4.注册bean
5.从beanFactory中获取bean
public class BeanFactoryTest {
@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", "你好 世界!"));
beanDefinition.setPropertyValues(propertyValues);
// 4.生成bean
beanFactory.registerBeanDefinition("helloWorldService", beanDefinition);
// 5.获取bean
HelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService");
helloWorldService.helloWorld();
}
}