spring手写源码二

bean包

Aware类

package com.lv.spring.bean;

/**
 * Created by lvyanghui
 * 2018/12/26 10:23
 */
public interface Aware {
}

BeanDefinition类

package com.lv.spring.bean;

import org.springframework.util.StringUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.List;

/**
 * Created by lvyanghui
 * 2018/11/28 9:35
 */
public interface BeanDefinition {


    String SCOPE_SINGLETON = "singleton";
    String SCOPE_PROTOTYPE = "prototype";

    Class<?> getBeanClass();

    String getScope();

    boolean isSingleton();
    boolean isPrototype();

    String getFactoryBeanName();
    String getFactoryMethodName();

    String getInitMethodName();

    String getDestroyMethodName();

    List<?> getConstructorArgumentValues();

    List<PropertyValue> getPropertyValues();

    public Object[] getConstructorArgumentRealValues();

    public void setConstructorArgumentRealValues(Object[] values);

    public Constructor getConstructor();

    public void setConstructor(Constructor constructor);

    public Method getFactoryMethod();

    public void setFactoryMethod(Method factoryMethod);

    default boolean validate(){

        if(this.getBeanClass() == null){
            if(StringUtils.isEmpty(this.getFactoryBeanName()) || StringUtils.isEmpty(this.getFactoryMethodName())){
                return false;
            }
        }else{
            if(!StringUtils.isEmpty(this.getFactoryBeanName())){
                return false;
            }
        }
        return true;
    }

}

BeanDefinitionRegistry类

package com.lv.spring.bean;

/**
 * Created by lvyanghui
 * 2018/12/19 14:23
 */
public interface BeanDefinitionRegistry {

    void registerBeanDefinition(String beanName,BeanDefinition beanDefinition)throws BeanDefinitionRegistryException;

    BeanDefinition getBeanDefinition(String beanName);

    boolean containsBeanDefinition(String beanName);
}

BeanDefinitionRegistryException类

package com.lv.spring.bean;

/**
 * Created by lvyanghui
 * 2018/12/20 11:07
 */
public class BeanDefinitionRegistryException extends Exception{


    public BeanDefinitionRegistryException(){
        super();
    }

    public BeanDefinitionRegistryException(Throwable cause){
        super(cause);
    }

    public BeanDefinitionRegistryException(String message){
        super(message);
    }

    public BeanDefinitionRegistryException(String message,Throwable cause){
        super(message,cause);
    }
}

BeanFactory类

package com.lv.spring.bean;

/**
 * Created by lvyanghui
 * 2018/12/19 14:21
 */
public interface BeanFactory {

    Object getBean(String beanName) throws Exception;

    void registryBeanPostProcessor(BeanPostProcessor beanPostProcessor);
}

BeanFactoryAware类

package com.lv.spring.bean;

/**
 * Created by lvyanghui
 * 2018/12/26 10:24
 */
public interface BeanFactoryAware extends Aware{

    void setBeanFactory(BeanFactory beanFactory);
}

BeanPostProcessor类

package com.lv.spring.bean;

/**
 * Created by lvyanghui
 * 2018/12/26 10:25
 */
public interface BeanPostProcessor {

    default Object postProcessBeforeInitialization(String beanName,Object bean){

        return bean;
    }

    default Object postProcessAfterInitialization(String beanName,Object bean){

        return bean;
    }
}

BeanRefernerce类

package com.lv.spring.bean;

/**
 * Created by lvyanghui
 * 2018/12/21 10:10
 */
public class BeanRefernerce {

    private String beanName;

    public BeanRefernerce(String beanName) {
        this.beanName = beanName;
    }

    public String getBeanName() {
        return beanName;
    }

    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }
}

DefaultBeanFactory类

package com.lv.spring.bean;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by lvyanghui
 * 2018/12/19 14:50
 */
public class DefaultBeanFactory implements BeanFactory,BeanDefinitionRegistry,Closeable {

    private Map<String,BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
    private Map<String,Object> beanMap = new ConcurrentHashMap<String,Object>(256);

    private ThreadLocal<Set<String>> buildingBeans = new ThreadLocal<>();

    private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();

    @Override
    public void registryBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        beanPostProcessorList.add(beanPostProcessor);
        if(beanPostProcessor instanceof BeanFactoryAware){
            ((BeanFactoryAware) beanPostProcessor).setBeanFactory(this);
        }
    }

    @Override
    public void registerBeanDefinition(String beanName,BeanDefinition beanDefinition) throws BeanDefinitionRegistryException{

        Objects.requireNonNull(beanName,"beanName不能为空!");
        Objects.requireNonNull(beanDefinition,"beanDefinition不能为空!");

        if(!beanDefinition.validate()){
            throw new BeanDefinitionRegistryException("验证beanDefinition参数不合法");
        }
        if(beanDefinitionMap.containsKey(beanName)){
            throw new BeanDefinitionRegistryException("已经存在beanDefinition");
        }

        beanDefinitionMap.put(beanName,beanDefinition);
    }

    @Override
    public BeanDefinition getBeanDefinition(String beanName) {
        return beanDefinitionMap.get(beanName);
    }

    @Override
    public boolean containsBeanDefinition(String beanName) {
        return beanDefinitionMap.containsKey(beanName);
    }

    @Override
    public Object getBean(String beanName) throws Exception{
        return doGetBean(beanName);
    }


    protected Object doGetBean(String beanName) throws Exception {
        Objects.requireNonNull(beanName,"beanName不能为空");

        Object instance = beanMap.get(beanName);
        if(null != instance){
            return instance;
        }

        BeanDefinition beanDefinition = getBeanDefinition(beanName);
        Objects.requireNonNull(beanDefinition, "beanDefinition不能为空");

        Set<String> ingBeans = this.buildingBeans.get();
        if(null == ingBeans){
            ingBeans = new HashSet<>();
            this.buildingBeans.set(ingBeans);
        }

        if(ingBeans.contains(beanName)){
            throw new Exception(beanName + " 循环依赖!" + ingBeans);
        }

        ingBeans.add(beanName);

        Class<?> classType = beanDefinition.getBeanClass();
        if(classType != null){

            if(beanDefinition.getFactoryMethodName() == null){
                instance = createInstanceByConstructor(beanDefinition);
            }else{
                instance = createInstanceByStaticFactoryMethod(beanDefinition);
            }
        }else{
            instance = createInstanceByFactoryMethod(beanDefinition);
        }

        ingBeans.remove(beanName);

        setPropertyDIValues(beanDefinition,instance);

        instance = applyPostProcessBeforeInitialization(beanName,instance);

        doInitMethod(beanDefinition,instance);

        instance = applyPostProcessAfterInitialization(beanName,instance);

        if(beanDefinition.isSingleton()){
            beanMap.put(beanName,instance);
        }

        return instance;
    }

    public Object createInstanceByConstructor(BeanDefinition beanDefinition)throws Exception{
        try{

            Object[] args = getConstructorArgumentValues(beanDefinition);
            if (null == args) {
                return beanDefinition.getBeanClass().newInstance();
            }else{
                return determinConstructor(beanDefinition,args).newInstance(args);
            }
        }catch (Exception e){
            throw new Exception("创建bean的实例异常,beanDefinition:" + beanDefinition + e.getMessage());
        }
    }

    public Object createInstanceByStaticFactoryMethod(BeanDefinition beanDefinition)throws Exception{

        Class<?> classType = beanDefinition.getBeanClass();
        Object[] args = getRealValues(beanDefinition.getConstructorArgumentValues());
        Method method = determinMethod(beanDefinition,args,null);
        return method.invoke(classType,args);
    }

    public Object createInstanceByFactoryMethod(BeanDefinition beanDefinition)throws Exception{

        Object factoryBean = doGetBean(beanDefinition.getFactoryBeanName());
        Object[] args = getRealValues(beanDefinition.getConstructorArgumentValues());
        Method method = determinMethod(beanDefinition, args,factoryBean.getClass());

        return method.invoke(factoryBean,args);
    }

    public Object[] getRealValues(List<?> defs)throws Exception{

        if(CollectionUtils.isEmpty(defs)){
            return null;
        }

        Object[] realValues = new Object[defs.size()];

        Object realValue = null;
        int i = 0;
        for(Object rv : defs){

            realValue = resolvePropertyValue(rv);
            realValues[i++] = realValue;
        }

        return realValues;
    }

    private Object[] getConstructorArgumentValues(BeanDefinition bd) throws Exception {

        return this.getRealValues(bd.getConstructorArgumentValues());

    }

    public void doInitMethod(BeanDefinition beanDefinition,Object instance) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        String initMethod = beanDefinition.getInitMethodName();
        if(StringUtils.isNotBlank(initMethod)){
            Method method = instance.getClass().getMethod(initMethod, null);
            method.invoke(instance,null);
        }
    }

    public Constructor<?> determinConstructor(BeanDefinition beanDefinition,Object[] args)throws Exception{

        Constructor ctr = null;

        if(null == args){
            return beanDefinition.getBeanClass().getConstructor();
        }

        ctr = beanDefinition.getConstructor();
        if(null != ctr){
            return ctr;
        }

        Class[] paramTypes = new Class[args.length];
        for (int i = 0, len = args.length; i < len; i++) {
            paramTypes[i] = args[i].getClass();
        }

        try{
            ctr = beanDefinition.getBeanClass().getConstructor(paramTypes);
        }catch (Exception e){

        }

        if(null == ctr){
            Constructor<?>[] constructors = beanDefinition.getBeanClass().getConstructors();
            outer: for(Constructor constructor : constructors){

                Class[] parameterTypes = constructor.getParameterTypes();
                if(parameterTypes.length == args.length){
                    for (int j = 0,leng = parameterTypes.length; j < leng; j++) {

                        if(!parameterTypes[j].isAssignableFrom(args[j].getClass())){
                            continue outer;
                        }
                    }
                    ctr = constructor;
                    break outer;
                }
            }
        }

        if(null != ctr){

            beanDefinition.setConstructor(ctr);
            return ctr;
        }else{
            throw new Exception("找不到构造器");
        }

    }

    public Method determinMethod(BeanDefinition beanDefinition,Object[] args,Class<?> classType)throws Exception{

        if(null == classType){
            classType = beanDefinition.getBeanClass();
        }

        Method method = null;

        String methodName = beanDefinition.getFactoryMethodName();
        if(null == args){
            return classType.getMethod(methodName);
        }

        method = beanDefinition.getFactoryMethod();
        if(null != method){
            return method;
        }

        Class[] paramTypes = new Class[args.length];
        for (int i = 0, len = args.length; i < len; i++) {
            paramTypes[i] = args[i].getClass();
        }

        try{
            method = classType.getMethod(methodName,paramTypes);
        }catch (Exception e){

        }

        if(null == method){
            Method[] methods = classType.getMethods();

            outer: for(Method me : methods){
                if(!me.getName().equals(methodName)){
                    continue ;
                }else{
                    Class<?>[] parameterTypes = me.getParameterTypes();
                    if(parameterTypes.length == args.length){
                        for (int j = 0,leng = parameterTypes.length; j < leng; j++) {

                            if(!parameterTypes[j].isAssignableFrom(args[j].getClass())){
                                continue outer;
                            }
                        }
                        method = me;
                        break outer;
                    }
                }
            }
        }

        if(null != method){
            beanDefinition.setFactoryMethod(method);
            return method;
        }else{
            throw new Exception("找不到方法");
        }
    }


    public void setPropertyDIValues(BeanDefinition beanDefinition,Object intance)throws Exception{

        List<PropertyValue> propertyValues = beanDefinition.getPropertyValues();
        if(!CollectionUtils.isEmpty(propertyValues)){

            for(PropertyValue propertyValue : propertyValues){
                if(StringUtils.isEmpty(propertyValue.getName())){
                    continue;
                }

                Class<?> clazz = intance.getClass();
                Field field = clazz.getDeclaredField(propertyValue.getName());

                field.setAccessible(true);

                Object realValue = resolvePropertyValue(propertyValue.getValue());

                field.set(intance,realValue);
            }
        }

    }

    public Object resolvePropertyValue(Object value)throws Exception{

        Object realValue = null;

        if(null != value){
            if(value instanceof BeanRefernerce){
                realValue = getBean(((BeanRefernerce) value).getBeanName());
            } else if (value instanceof Object[]) {

            } else if (value instanceof Collection) {

            } else if (value instanceof Properties) {

            } else if (value instanceof Map) {

            } else {
                realValue = value;
            }
        }

        return realValue;
    }

    public Object applyPostProcessBeforeInitialization(String beanName,Object instance){

        for(BeanPostProcessor beanPostProcessor : beanPostProcessorList){
            instance = beanPostProcessor.postProcessBeforeInitialization(beanName,instance);
        }

        return instance;

    }


    public Object applyPostProcessAfterInitialization(String beanName,Object instance){

        for(BeanPostProcessor beanPostProcessor : beanPostProcessorList){
            instance = beanPostProcessor.postProcessAfterInitialization(beanName,instance);
        }

        return instance;
    }

    @Override
    public void close() throws IOException {
        //执行单例实例的销毁方法

        for(Map.Entry<String,BeanDefinition> entry : beanDefinitionMap.entrySet()){
            String beanName = entry.getKey();
            BeanDefinition beanDefinition = entry.getValue();

            if(beanDefinition.isSingleton() && !StringUtils.isEmpty(beanDefinition.getDestroyMethodName())){

                Object instance = beanMap.get(beanName);
                try {
                    Method method = instance.getClass().getMethod(beanDefinition.getDestroyMethodName(),null);

                    method.invoke(instance,null);

                } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

GenericBeanDefinition类

package com.lv.spring.bean;

import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.List;

/**
 * Created by lvyanghui
 * 2018/12/19 14:42
 */
public class GenericBeanDefinition implements BeanDefinition{

    private Class<?> beanClass;
    private String scope=SCOPE_SINGLETON;
    private String factoryBeanName;
    private String factoryMethodName;
    private String initMethodName;
    private String destroyMethodName;

    private Constructor constructor;
    private Method factoryMethod;

    private List<?> constructorArgumentValues;
    private List<PropertyValue> propertyValues;

    private ThreadLocal<Object[]> realConstructorArgumentValues = new ThreadLocal<>();

    @Override
    public Object[] getConstructorArgumentRealValues() {
        return realConstructorArgumentValues.get();
    }

    @Override
    public void setConstructorArgumentRealValues(Object[] values) {
        realConstructorArgumentValues.set(values);
    }

    public void setBeanClass(Class<?> beanClass) {
        this.beanClass = beanClass;
    }

    public void setScope(String scope) {
        if(StringUtils.isNotBlank(scope)){
            this.scope = scope;
        }
    }

    public void setFactoryBeanName(String factoryBeanName) {
        this.factoryBeanName = factoryBeanName;
    }

    public void setFactoryMethodName(String factoryMethodName) {
        this.factoryMethodName = factoryMethodName;
    }

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

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

    public void setConstructorArgumentValues(List<?> constructorArgumentValues) {
        this.constructorArgumentValues = constructorArgumentValues;
    }

    public void setPropertyValues(List<PropertyValue> propertyValues) {
        this.propertyValues = propertyValues;
    }

    @Override
    public Class<?> getBeanClass() {
        return beanClass;
    }

    @Override
    public String getScope() {
        return scope;
    }

    @Override
    public boolean isSingleton() {
        return SCOPE_SINGLETON.equals(scope);
    }

    @Override
    public boolean isPrototype() {
        return SCOPE_PROTOTYPE.equals(scope);
    }

    @Override
    public String getFactoryBeanName() {
        return factoryBeanName;
    }

    @Override
    public String getFactoryMethodName() {
        return factoryMethodName;
    }

    @Override
    public String getInitMethodName() {
        return initMethodName;
    }

    @Override
    public String getDestroyMethodName() {
        return destroyMethodName;
    }


    @Override
    public List<?> getConstructorArgumentValues() {
        return constructorArgumentValues;
    }

    @Override
    public List<PropertyValue> getPropertyValues() {
        return propertyValues;
    }

    public Constructor getConstructor() {
        return constructor;
    }

    public void setConstructor(Constructor constructor) {
        this.constructor = constructor;
    }

    public Method getFactoryMethod() {
        return factoryMethod;
    }

    public void setFactoryMethod(Method factoryMethod) {
        this.factoryMethod = factoryMethod;
    }

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

        GenericBeanDefinition that = (GenericBeanDefinition) o;

        if (beanClass != null ? !beanClass.equals(that.beanClass) : that.beanClass != null) return false;
        if (destroyMethodName != null ? !destroyMethodName.equals(that.destroyMethodName) : that.destroyMethodName != null)
            return false;
        if (factoryBeanName != null ? !factoryBeanName.equals(that.factoryBeanName) : that.factoryBeanName != null)
            return false;
        if (factoryMethodName != null ? !factoryMethodName.equals(that.factoryMethodName) : that.factoryMethodName != null)
            return false;
        if (initMethodName != null ? !initMethodName.equals(that.initMethodName) : that.initMethodName != null)
            return false;
        if (scope != null ? !scope.equals(that.scope) : that.scope != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = beanClass != null ? beanClass.hashCode() : 0;
        result = 31 * result + (scope != null ? scope.hashCode() : 0);
        result = 31 * result + (factoryBeanName != null ? factoryBeanName.hashCode() : 0);
        result = 31 * result + (factoryMethodName != null ? factoryMethodName.hashCode() : 0);
        result = 31 * result + (initMethodName != null ? initMethodName.hashCode() : 0);
        result = 31 * result + (destroyMethodName != null ? destroyMethodName.hashCode() : 0);
        return result;
    }
}

PreBuildBeanFactory类

package com.lv.spring.bean;

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

/**
 * Created by lvyanghui
 * 2018/12/25 14:14
 */
public class PreBuildBeanFactory extends DefaultBeanFactory{


    private List<String> beanNames = new ArrayList<>();
    @Override
    public void registerBeanDefinition(String beanName,BeanDefinition beanDefinition) throws BeanDefinitionRegistryException{

        super.registerBeanDefinition(beanName,beanDefinition);
        synchronized (beanNames){
            beanNames.add(beanName);
        }
    }

    public void preInstantiateSingletons()throws Exception{
        synchronized (beanNames){
            for(String beanName : beanNames){
                BeanDefinition beanDefinition = getBeanDefinition(beanName);
                if(beanDefinition.isSingleton()){
                    doGetBean(beanName);
                }
            }
        }


    }

}

PropertyValue类

package com.lv.spring.bean;

/**
 * Created by lvyanghui
 * 2018/12/21 9:47
 */
public class PropertyValue {

    private String name;
    private Object value;

    public PropertyValue(String name, Object value) {
        this.name = name;
        this.value = value;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Object getValue() {
        return value;
    }

    public void setValue(Object value) {
        this.value = value;
    }
}

猜你喜欢

转载自blog.csdn.net/fengyingsuixu/article/details/86513099
今日推荐