spring源码

BeanDefinition

 

package com.lv.spring.bean;

import org.springframework.util.StringUtils;

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

    List<PropertyValue> getPropertyValues();

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

BeanRefernerce

package com.lv.spring.bean;

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

    private String name;

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

    public String getName() {
        return name;
    }

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

 

DefaultBeanFactory

 

package com.lv.spring.bean;

import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
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);

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


    public 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不能为空");

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

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

        doInitMethod(beanDefinition,instance);

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

        return instance;
    }

    public Object createInstanceByConstructor(BeanDefinition beanDefinition)throws Exception{

        Class<?> classType = beanDefinition.getBeanClass();
        Object[] args = getRealValues(beanDefinition.getConstructorValues());
        if(null == args){
            return classType.newInstance();
        }else{
            Constructor constructor = determinConstructor(beanDefinition,args);
            if(null == constructor){
                return classType.newInstance();
            }else{
                return constructor.newInstance(args);
            }
        }
    }

    public Object createInstanceByStaticFactoryMethod(BeanDefinition beanDefinition)throws Exception{

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

    public Object createInstanceByFactoryMethod(BeanDefinition beanDefinition)throws Exception{

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

        return method.invoke(factoryBean,args);
    }

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

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

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

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

            Class[] parameterTypes = constructor.getParameterTypes();
            int i = 0;
            if(parameterTypes.length == args.length){
                for(Object arg : args){

                    if(!parameterTypes[i++].isAssignableFrom(arg.getClass())){
                        continue outer;
                    }
                    if(i == args.length){
                        return constructor;
                    }
                }
            }
        }

        return null;
    }

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

        Method method = null;

        if(null == args){
            method = classType.getMethod(beanDefinition.getFactoryMethodName());
        }
        Method[] methods = classType.getMethods();

        outer: for(Method me : methods){
            if(!me.getName().equals(beanDefinition.getFactoryMethodName())){
                continue ;
            }else{
                Class<?>[] parameterTypes = me.getParameterTypes();
                int i = 0;
                if(args.length == parameterTypes.length){
                    for(Object arg : args){
                        if(!parameterTypes[i++].isAssignableFrom(arg.getClass())){
                            continue outer;
                        }

                        if(i == args.length){
                            return me;
                        }
                    }
                }
            }
        }
        if(null == method){
            throw new Exception("找不到方法");
        }
        return method;
    }

    public Object[] getRealValues(List<PropertyValue> propertyValues)throws Exception{

        Object[] realValues = null;
        if(!CollectionUtils.isEmpty(propertyValues)){
            List<PropertyValue> resolvedPropertyValues = resolvePropertyValues(propertyValues);
            realValues = new Object[resolvedPropertyValues.size()];
            for(int i = 0,len = resolvedPropertyValues.size(); i < len; i++){
                realValues[i] = resolvedPropertyValues.get(i).getValue();
            }
        }
        return realValues;
    }


    public List<PropertyValue> resolvePropertyValues(List<PropertyValue> propertyValues)throws Exception{


        List<PropertyValue> resolvedPropertyValues = new ArrayList<>();

        Object value = null;
        for(PropertyValue propertyValue : propertyValues){

            value = propertyValue.getValue();

            if(value instanceof BeanRefernerce){
                propertyValue.setValue(getBean(((BeanRefernerce) value).getName()));
            }else if(value instanceof String){
                propertyValue.setValue(String.valueOf(value));
            }else if(value instanceof Integer){

            }else if(value instanceof List){

            } else if(value instanceof Map){

            }

            resolvedPropertyValues.add(propertyValue);
        }
        return resolvedPropertyValues;
    }

    @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.springframework.util.StringUtils;

import java.util.ArrayList;
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 List<PropertyValue> constructorValues = new ArrayList<>();
    private List<PropertyValue> propertyValues = new ArrayList<>();

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

    public void setScope(String scope) {
        if(!StringUtils.isEmpty(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 setConstructorValues(List<PropertyValue> constructorValues) {
        this.constructorValues = constructorValues;
    }

    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<PropertyValue> getConstructorValues() {
        return constructorValues;
    }

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

    @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.equals(that.beanClass)) return false;
        if (!destroyMethodName.equals(that.destroyMethodName)) return false;
        if (!factoryBeanName.equals(that.factoryBeanName)) return false;
        if (!factoryMethodName.equals(that.factoryMethodName)) return false;
        if (!initMethodName.equals(that.initMethodName)) return false;
        if (!scope.equals(that.scope)) return false;

        return true;
    }

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


}

 

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

 

ABean

 

package com.lv.spring.test;

/**
 * Created by lvyanghui
 * 2018/12/19 16:44
 */
public class ABean {

    public void initMethod(){

        System.out.println("ABean 执行初始化方法.....");
    }

    public void methodA(){
        System.out.println("ABean 执行methodA.......");
    }

    public void destoryA(){
        System.out.println("ABean 执行destoryA.......");
    }


}

 

ABeanFactory

 

package com.lv.spring.test;

/**
 * Created by lvyanghui
 * 2018/12/19 16:44
 */
public class ABeanFactory {


    public static ABean getBeanByFactory(){

        return new ABean();
    }

    public ABean getBeanByFactoryBean(){

        return new ABean();
    }

}

 

BBean

 

package com.lv.spring.test;

/**
 * Created by lvyanghui
 * 2018/12/19 16:44
 */
public class BBean {

    private String name;

    private ABean aBean;

    public BBean() {
    }

    public BBean(String name) {
        this.name = name;
    }

    public BBean(String name, ABean aBean) {
        this.name = name;
        this.aBean = aBean;
    }

    public String getName() {
        return name;
    }

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

    public ABean getaBean() {
        return aBean;
    }

    public void setaBean(ABean aBean) {
        this.aBean = aBean;
    }
}

BBeanFactory

 

package com.lv.spring.test;

/**
 * Created by lvyanghui
 * 2018/12/19 16:44
 */
public class BBeanFactory {


    public static BBean getBeanByFactory(String name, ABean aBean){

        return new BBean();
    }

    public BBean getBeanByFactoryBean(String name, ABean aBean,String kk){

        return new BBean();
    }

}

 

BeanFactoryDITest

package com.lv;


import com.lv.spring.bean.BeanRefernerce;
import com.lv.spring.bean.DefaultBeanFactory;
import com.lv.spring.bean.GenericBeanDefinition;
import com.lv.spring.bean.PropertyValue;
import com.lv.spring.test.ABean;
import com.lv.spring.test.BBean;
import com.lv.spring.test.BBeanFactory;
import org.junit.Test;

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

/**
 * Created by lvyanghui
 * 2018/12/19 16:46
 */
public class BeanFactoryDITest {

    static DefaultBeanFactory beanFactory = new DefaultBeanFactory();

    @Test
    public void registerConstructorDI()throws Exception{

        GenericBeanDefinition bd = new GenericBeanDefinition();
        bd.setBeanClass(ABean.class);
        beanFactory.registerBeanDefinition("aa", bd);

        bd = new GenericBeanDefinition();
        bd.setBeanClass(BBean.class);

        PropertyValue property1 = new PropertyValue("name","lvyanghui");
        BeanRefernerce beanRefernerce = new BeanRefernerce("aa");
        PropertyValue property2 = new PropertyValue("ref",beanRefernerce);

        PropertyValue property3 = new PropertyValue("kkk","ssdfsdf");
        List<PropertyValue> propertyValues = new ArrayList<>();
        propertyValues.add(property1);
        propertyValues.add(property2);
        propertyValues.add(property3);
        bd.setConstructorValues(propertyValues);

        beanFactory.registerBeanDefinition("bb",bd);

        BBean bBean = (BBean)beanFactory.getBean("bb");
        System.out.println(bBean);

    }

    @Test
    public void registerStaticFactoryMethod()throws Exception{

        GenericBeanDefinition bd = new GenericBeanDefinition();
        bd.setBeanClass(ABean.class);
        beanFactory.registerBeanDefinition("aa", bd);

        bd = new GenericBeanDefinition();
        bd.setBeanClass(BBeanFactory.class);
        bd.setFactoryMethodName("getBeanByFactory");

        PropertyValue property1 = new PropertyValue("name","lvyanghui");
        BeanRefernerce beanRefernerce = new BeanRefernerce("aa");
        PropertyValue property2 = new PropertyValue("ref",beanRefernerce);

        //PropertyValue property3 = new PropertyValue("kkk","ssdfsdf");
        List<PropertyValue> propertyValues = new ArrayList<>();
        propertyValues.add(property1);
        propertyValues.add(property2);
        //propertyValues.add(property3);
        bd.setConstructorValues(propertyValues);

        beanFactory.registerBeanDefinition("factoryMethod",bd);

        BBean bBean = (BBean)beanFactory.getBean("factoryMethod");
        System.out.println(bBean);
    }

    @Test
    public void registerFactoryMethod()throws Exception{

        GenericBeanDefinition bd = new GenericBeanDefinition();
        bd.setBeanClass(ABean.class);
        beanFactory.registerBeanDefinition("aa", bd);

        bd = new GenericBeanDefinition();
        bd.setBeanClass(BBeanFactory.class);
        String fbname = "factory";
        beanFactory.registerBeanDefinition(fbname, bd);

        bd = new GenericBeanDefinition();
        bd.setFactoryBeanName(fbname);
        bd.setFactoryMethodName("getBeanByFactoryBean");

        PropertyValue property1 = new PropertyValue("name","lvyanghui");
        BeanRefernerce beanRefernerce = new BeanRefernerce("aa");
        PropertyValue property2 = new PropertyValue("ref",beanRefernerce);

        PropertyValue property3 = new PropertyValue("kk","ssdfsdf");
        List<PropertyValue> propertyValues = new ArrayList<>();
        propertyValues.add(property1);
        propertyValues.add(property2);
        propertyValues.add(property3);
        bd.setConstructorValues(propertyValues);

        beanFactory.registerBeanDefinition("factoryBean",bd);

        BBean bBean = (BBean)beanFactory.getBean("factoryBean");
        System.out.println(bBean);


    }
}

 

BeanFactoryTest

 

package com.lv;


import com.lv.spring.bean.BeanDefinitionRegistryException;
import com.lv.spring.bean.DefaultBeanFactory;
import com.lv.spring.bean.GenericBeanDefinition;
import com.lv.spring.test.ABean;
import com.lv.spring.test.ABeanFactory;
import org.junit.AfterClass;
import org.junit.Test;

/**
 * Created by lvyanghui
 * 2018/12/19 16:46
 */
public class BeanFactoryTest {

    static DefaultBeanFactory beanFactory = new DefaultBeanFactory();

    @Test
    public void register()throws BeanDefinitionRegistryException{

        GenericBeanDefinition bd = new GenericBeanDefinition();
        bd.setBeanClass(ABean.class);
        //bd.setScope("singleton");
        //bd.setScope("prototype");
        bd.setInitMethodName("initMethod");
        beanFactory.registerBeanDefinition("aa", bd);
    }

    @Test
    public void registerStaticFactoryMethod()throws BeanDefinitionRegistryException{

        GenericBeanDefinition bd = new GenericBeanDefinition();
        bd.setBeanClass(ABeanFactory.class);
        bd.setFactoryMethodName("getBeanByFactory");

        beanFactory.registerBeanDefinition("bb", bd);
    }

    @Test
    public void registerFactoryMethod()throws BeanDefinitionRegistryException{

        GenericBeanDefinition bd = new GenericBeanDefinition();
        bd.setBeanClass(ABeanFactory.class);
        String fbname = "factory";
        beanFactory.registerBeanDefinition(fbname, bd);

        bd = new GenericBeanDefinition();
        bd.setFactoryBeanName(fbname);
        bd.setFactoryMethodName("getBeanByFactoryBean");
        beanFactory.registerBeanDefinition("factoryBean",bd);

    }

    @AfterClass
    public static void testFactory()throws Exception{

        System.out.println("spring 构造方式------------");
        for (int i = 0; i < 3; i++) {
            ABean abean = (ABean)beanFactory.getBean("aa");
            System.out.println(abean);
        }


        System.out.println("spring 静态工厂方式------------");
        for (int i = 0; i < 3; i++) {
            ABean abean = (ABean)beanFactory.getBean("bb");
            System.out.println(abean);
        }

        System.out.println("spring 工厂方法方式------------");
        for (int i = 0; i < 3; i++) {
            ABean abean = (ABean)beanFactory.getBean("factoryBean");
            System.out.println(abean);
        }
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值