spring原理(一)

发布时间 2023-12-27 22:56:13作者: 辉辉、

定义bean类的属性值类

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;
    }
}

定义bean类的属性多类

public class PropertyValues {
    private final List<PropertyValue> propertyValues = new ArrayList<>();


    //追加资源
    public void addPropertyValues(PropertyValue pv) {
        //属性值内容一样替换掉
        for (Integer i = 0; i < propertyValues.size(); i++) {
            PropertyValue propertyValue = propertyValues.get(i);
            if (propertyValue.getName().equals(pv.getName())) {
                propertyValues.set(i, pv);
            }
        }

        //追加属性值
        propertyValues.add(pv);
    }

    //获取所有资源
    public PropertyValue[] getPropertyValue() {
        return this.propertyValues.toArray(new PropertyValue[0]);
    }
}

创建beanDefinition 定义类(是bean的实际承载类)

public class BeanDefinition {
    public static String SCOPE_SINGLETON = "singleton";
    private static String SCOPE_PROTOTYPE = "prototype";

    //class类
    private Class beanClass;

    /**
     * class 属性值
     */
    private PropertyValues propertyValues;

    /**
     * 类的初始化方法 - 对应xml的init-method
     */
    private String initMethodName;

    /**
     * 类的初始化方法 - 对应xml的init-destroy
     */
    private String destroyMethodName;

    /**
     * 作用域 - scope
     */
    private String scope = SCOPE_SINGLETON;
    private boolean singleton = true;
    private boolean prototype = false;

    /**
     * 懒加载
     */
    private boolean lazyInit = false;

    public BeanDefinition(Class beanClass) {
        this(beanClass, null);
    }

    public BeanDefinition(Class beanClass, PropertyValues propertyValues) {
        this.beanClass = beanClass;
        this.propertyValues = propertyValues != null ? propertyValues : new PropertyValues();  //确保资源类已初始化
    }

    public void setScope(String scope) {
        this.scope = scope;
        this.singleton = SCOPE_SINGLETON.equals(scope);
        this.prototype = SCOPE_PROTOTYPE.equals(scope);
    }

    public boolean isSingleton() {
        return singleton;
    }

    public boolean isPrototype() {
        return prototype;
    }
    public void setPropertyValues(PropertyValues propertyValues) {
        this.propertyValues = propertyValues;
    }

    public String getInitMethodName() {
        return initMethodName;
    }

    public void setInitMethodName(String initMethodName) {
        this.initMethodName = initMethodName;
    }

    public String getDestroyMethodName() {
        return destroyMethodName;
    }

    public void setDestroyMethodName(String destroyMethodName) {
        this.destroyMethodName = destroyMethodName;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        BeanDefinition that = (BeanDefinition) o;
        return beanClass.equals(that.beanClass);
    }

    @Override
    public int hashCode() {
        return Objects.hash(beanClass);
    }

    public void setLazyInit(boolean b){
        lazyInit=b;
    }

    public boolean isLazyInit(){
        return lazyInit;
    }
}

 

定义注册表基础接口:

注册表其实就是ConcurrentHashMap,上面beanDefinition会放入其中。但第一次获取会注入加入到三级缓存,后续会写到。

package org.springframework.beans.factory.supper;

import org.springframework.beans.factory.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;

public interface BeanDefinitionRegistry {
    /**
     * 向注册表中注BeanDefinition
     *
     * @param beanName
     * @param BeanDefinition
     */
    void registryBeanDefinition(String beanName, BeanDefinition BeanDefinition);

    /**
     * 向注册表里获取BeanDefinition
     *
     * @param beanName
     */
    BeanDefinition getBeanDefinition(String beanName) throws BeansException;

    /**
     * 注册表是否存在BeanDefinition
     *
     * @param beanName
     */
    boolean containsBeanDefinition(String beanName);
}

 实现bean容器:此处实现容器功能

public class DefaultListableBeanFactory implements BeanDefinitionRegistry {
    private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();

    @Override
    public void registryBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName, beanDefinition);
    }

    @Override
    public BeanDefinition getBeanDefinition(String beanName) throws BeansException {
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if (beanDefinition == null) {
            throw new BeansException("找不到 beanName:" + beanName);
        }
        return beanDefinition;
    }

    @Override
    public boolean containsBeanDefinition(String beanName) {
        return beanDefinitionMap.get(beanName) != null;
    }
}

 

结合以上代码进行实例测试

package org.springFramework.test.ioc;

import org.junit.jupiter.api.Test;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.PropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.supper.DefaultListableBeanFactory;

import java.util.ArrayList;
import java.util.List;

public class BeanDefinitionAndBeanDefinitionRegistryTest {
    @Test
    public void testBeanFactory() throws Exception {
        //定义类值
        PropertyValues propertyValues = new PropertyValues();
        propertyValues.addPropertyValues(new PropertyValue("age", "50"));
        propertyValues.addPropertyValues(new PropertyValue("name", "小辉"));

        //生成bean对象
        BeanDefinition beanDefinition = new BeanDefinition(ServiceUser.class, propertyValues);

        //放入map中
        DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
        defaultListableBeanFactory.registryBeanDefinition("serverUser", beanDefinition);

        //获取指定serverUser
        BeanDefinition serviceUser = defaultListableBeanFactory.getBeanDefinition("serverUser");

        System.out.println();
    }
}