《手写Spring渐进式源码实践》-第三章 基于Cglib实现含构造函数的类实例化策略

本章目的:基于策略模式实现两种用于实例化对象的方法,如JDK、Cglib,并基于此方法实现含有带入参信息的构造函数的类实例化策略。
以下是源码:

public class BeanDefinition {
    private Class bean;

    public BeanDefinition(Class bean) {
        this.bean = bean;
    }

    public Class getBean() {
        return bean;
    }

    public void setBean(Class bean) {
        this.bean = bean;
    }
}
public interface SingletonBeanRegistry {
    Object getSingleton(String beanName);

    void registrySingletonBean(String name,Object singleton);
}
public abstract class AbstractAutowireCapableBeanFactory extends AbstractoryBeanFactory {
    //实例化cblib的实例化策略
    InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiation();
    @Override
    protected Object createBean(String beanName, BeanDefinition beanDefinition,Object[] args) throws BeansException {
        Object bean;
        try {
            bean = createBeanInstance(beanDefinition,beanName,args);
        } catch (Exception e) {
            throw  new BeansException("Instantiation of bean failed", e);
        }
        super.registrySingletonBean(beanName,bean);
        return bean;
    }

    protected Object createBeanInstance(BeanDefinition beanDefinition,String beanName,Object[] args){
        Constructor constructorToUse = null;
        Class<?> beanClass = beanDefinition.getBean();
        Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            if(Objects.nonNull(args) && declaredConstructor.getParameterTypes().length ==args.length){
                constructorToUse = declaredConstructor;
                break;
            }
        }
        return getInstantiationStrategy().instantiate(beanDefinition,beanName,constructorToUse,args);
    }

    public InstantiationStrategy getInstantiationStrategy() {
        return instantiationStrategy;
    }
}
public abstract class AbstractoryBeanFactory extends DefauleSingletonBeanRegistry implements BeanFactory{
    @Override
    public Object getBean(String name) throws BeansException {
        return  doGetBean(name,null);
    }

    @Override
    public Object getBean(String name, Object... args) throws BeansException {
        return doGetBean(name,args);
    }

    private <T> T doGetBean(final String name,final Object[] args){
        Object singleton = getSingleton(name);
        if(Objects.nonNull(singleton)){
            return (T)singleton;
        }
        BeanDefinition beanDefinition = getBeanDefinition(name);
        return (T)createBean(name,beanDefinition,args);
    }

    protected abstract BeanDefinition getBeanDefinition(String beanName);

    protected abstract Object createBean(String beanName, BeanDefinition beanDefinition,Object[] args) throws BeansException;
}
public interface BeanDefinitionRegistry {
    void beanDefinitionRegistry(String name, BeanDefinition beanDefinition);
}
public interface BeanFactory {
    Object getBean(String name)throws BeansException;

    Object getBean(String name, Object ...args)throws BeansException;
}

实例化接口

public interface InstantiationStrategy {
    Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor,Object[] args)throws BeansException;
}

cglib实例化类,Cglib是基于ASM字节码框架实现的,后面会写一些相关的随笔。

public class CglibSubclassingInstantiation implements InstantiationStrategy{
    @Override
    public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(beanDefinition.getBean());
        enhancer.setCallback(new NoOp() {
            @Override
            public int hashCode() {
                return super.hashCode();
            }
        });
        if(Objects.isNull(ctor)){
            return enhancer.create();
        }
        //入参是构造函数的参数类型和参数值
        return enhancer.create(ctor.getParameterTypes(),args);
    }
}

jdk实例化类

public class SimpleInstantiationStrategy implements InstantiationStrategy{
    @Override
    public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException {
        Class clazz = beanDefinition.getBean();
        try {
            if(Objects.nonNull(ctor)) {
                //获取该类的构造方法,getDeclaredConstructor() 只匹配精确参数类型,不会自动装箱/拆箱
                return clazz.getDeclaredConstructor(ctor.getParameterTypes()).newInstance(args);
            }else{
                //获取无参构造
                return clazz.getDeclaredConstructor().newInstance();
            }
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException |NoSuchMethodException e) {
            throw  new BeansException("Failed to instantiate ["+clazz.getName()+"]",e);
        }
    }
}
public abstract class DefauleSingletonBeanRegistry implements SingletonBeanRegistry {
    Map<String,Object> singletonObjects = new HashMap<>();
    @Override
    public Object getSingleton(String beanName) {
        return singletonObjects.get(beanName);
    }

    @Override
    public void registrySingletonBean(String name, Object singleton) {
        singletonObjects.put(name,singleton);
    }
}
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry{
    private Map<String,BeanDefinition> beanDefinitionMap =  new HashMap<>();
    @Override
    protected BeanDefinition getBeanDefinition(String beanName) {
        try {
            return beanDefinitionMap.get(beanName);
        } catch (Exception e) {
            throw new BeansException( "No bean named "+beanName+" is deined");
        }
    }

    @Override
    public void beanDefinitionRegistry(String name, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(name,beanDefinition);
    }
}
public class BeansException extends RuntimeException{
    public BeansException(String msg){
        super(msg);
    }

    public BeansException(String msg,Throwable cause){
        super(msg,cause);
    }
}

单元测试的类:

public class UserService {

    private String name;

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

    public void queryUserInfo(){
        System.out.println("查询用户信息:"+name);
    }
}
@SpringBootTest(classes = MyApplication.class)
public class ApiTest {
    @Test
    public void test_BeanFactory(){
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.beanDefinitionRegistry("userService", new BeanDefinition(UserService.class));
        //第一次获取bean对象
        UserService userService = (UserService)beanFactory.getBean("userService","Charlie");
        userService.queryUserInfo();
    }
}

源码地址:https://github.com/Charlie-pang-sys/WeaponSystem/tree/master/Java/Spring-Tutorials/spring-step-03

posted @ 2025-06-01 22:10  Charlie-Pang  阅读(8)  评论(0)    收藏  举报