Spring手撸04:使用Cglib实现含有构造函数的类实现策略

上回书说到Spring 实现Bean定义/注册/创建的一个流程,但在创建的时候其实埋了个坑,今天这回书,就把这个坑填掉!

主要就是在实例化这个过程,只是草率的使用class.newInstance();

但其实这个方法已经被废弃掉了,因为这个方法必须要有无参构造方法,所以很不灵活.

所以今天就来重写一下获取实例化的方法.

BeanFactory

首先因为每个Bean的构造函数是不固定的,所以可以用这个方式来扩展一下getBean()

public interface BeanFactory {

    Object getBean(String name,Object... args);

}

AbstractBeanFactory

这里只要是改造了createBean添加了参数

然后就是去改造实现类AbstractBeanFactory

public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {

@Override
public Object getBean(String beanName,Object... args){
    //继承自DefaultSingletonBeanRegistry 的方法
    Object bean = getSingleton(beanName);
    if (bean != null){
        return bean;
    }
    //获取不到就两个抽象方法 让实现此类的去做实现
    BeanDefinition beanDefinition = getBeanDefinition(beanName);
    return createBean(beanName,beanDefinition,args);

}

protected abstract BeanDefinition getBeanDefinition(String name) throws BeansException;

//添加参数
protected abstract Object createBean(String beanName,BeanDefinition bean,Object... args) throws BeansException;

}

AbstractAutowireCapableBeanFactory

然后对实现这个createBean的类也小改造一下,主要是加了个实例化的方法来取代原来简单的实例化

@Getter
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory{

private InstantiationStrategy instantiationStrategy =new CglibSubclassingInstantiationStrategy();

@Override
protected Object createBean(String name, BeanDefinition beanDefinition,Object[] args) throws BeansException {
    Object bean;
    bean = createBeanInstance(name,beanDefinition,args);
    addSingletonBean(name,bean);
    return bean;
}

protected Object createBeanInstance(String name, BeanDefinition beanDefinition,Object[] args){
    Constructor constructor =null;
    Class beanClass = beanDefinition.getBeanClass();
    //获取所有的构造方法
    Constructor[] declaredConstructors = beanClass.getDeclaredConstructors();
    //简单对比 选择构造类型 spring还会对比类型
    for (Constructor ctor : declaredConstructors) {
        if (null!=args && ctor.getParameterTypes().length ==args.length){
            constructor=ctor;
            break;
        }
    }
    //创建
    return getInstantiationStrategy().instantiate(beanDefinition,name,constructor,args);
}

}

InstantiationStrategy

提供一个抽象方法,目的是根据提供的参数进行实例化

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

这里提供了两种实现方式

SimpleInstantiationStrategy

简易版

public class SimpleInstantiationStrategy implements InstantiationStrategy{

    @Override
    public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException {
        Class clazz = beanDefinition.getBeanClass();
        try {
            //如果是有参构造
            if (null!=ctor){
                return clazz.getDeclaredConstructor(ctor.getParameterTypes()).newInstance(args);
            }else {
                //无参构造
                return clazz.getDeclaredConstructor().newInstance();
            }
        }catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e){
            throw new BeansException("Failed to instantiate [" + clazz.getName() + "]", e);
        }

    }
}

CglibSubclassingInstantiationStrategy

不过Spring更喜欢用Cglib

public class CglibSubclassingInstantiationStrategy implements InstantiationStrategy{
    @Override
    public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(beanDefinition.getBeanClass());
        enhancer.setCallback(new NoOp() {
            @Override
            public int hashCode() {
                return super.hashCode();
            }
        });
        if (null == ctor)return enhancer.create();

        return enhancer.create(ctor.getParameterTypes(),args);
    }
}

最后开始测试

@Test
public void testBeanFactory(){
    //初始化 beanFactory
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    //创建 bean信息
    BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
    String beanName = "userService";
    //注册到工厂中
    beanFactory.registerBeanDefinition(beanName,beanDefinition);
    //获取实例
    UserService userService = (UserService) beanFactory.getBean(beanName,"小明");
    userService.queryUserInfo();
}

应该是addBeanPostProcessor()实现的方式不对,之前代码不完整,所以少了这块自己补的, 现在出问题了, 因为我之前暂时填了那个坑, 走向bean注册, 这样会导致的结果就是里面携带的参数丢失了.

所以去看一下人家源码怎么实现的,然后改造了一下!

这次直接把后处理器管理起来,这样就走得通了.

AbstractBeanFactory

package com.linnine.spring.beans.factory.support;


import com.linnine.spring.beans.BeansException;
import com.linnine.spring.beans.factory.config.BeanDefinition;
import com.linnine.spring.beans.factory.config.BeanPostProcessor;
import com.linnine.spring.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.List;
//09 从实现BeanFactory改成实现ConfigurableBeanFactory
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements ConfigurableBeanFactory {
    //09新增 管理后处理器 源码的获取不是通过new这个, 这里临时用一下
    private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();

    public Object getBean(String beanName,Object... args){
        //继承自DefaultSingletonBeanRegistry 的方法
        Object bean = getSingleton(beanName);
        if (bean != null){
            return bean;
        }
        //获取不到就两个抽象方法 让实现此类的去做实现
        BeanDefinition beanDefinition = getBeanDefinition(beanName);
        return createBean(beanName,beanDefinition,args);

    }

    protected abstract BeanDefinition getBeanDefinition(String name) throws BeansException;

    //添加参数
    protected abstract Object createBean(String beanName,BeanDefinition bean,Object... args) throws BeansException;

    //09 改造
    public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
        this.beanPostProcessors.remove(beanPostProcessor);
        this.beanPostProcessors.add(beanPostProcessor);
    }
    //09 转移 原本的获取改成从这里获取
    public BeanPostProcessor[] getBeanPostProcessors(){
        return this.beanPostProcessors.toArray(new BeanPostProcessor[0]);
    }
}

ConfigurableBeanFactory

之前一直没用到,现在也用到了

import com.linnine.spring.beans.factory.BeanFactory;

//09 改成接口 实现BeanFactory
public interface ConfigurableBeanFactory extends BeanFactory {

    //09 添加一个接口方法
    void addBeanPostProcessor(BeanPostProcessor var1);

}

ConfigurableListableBeanFactory

//09 多实现了后面两个
public interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory,ConfigurableBeanFactory {

void preInstantiateSingletons();

//09去除添加后处理器的方法

BeanDefinition getBeanDefinition(String name);

void destroySingletons();

}

DefaultListableBeanFactory

也是去除了之前自己的暂时实现方法
在这里插入图片描述
这样就能通了

执行:init-method
ClassLoader:jdk.internal.loader.ClassLoaders$AppClassLoader@2c13da15
Bean Name is:userService
执行:UserService.afterPropertiesSet
测试结果:小傅哥10001腾讯深圳
ApplicationContextAware:com.linnine.spring.context.support.ClassPathXmlApplicationContext@304bb45b
BeanFactoryAware:com.linnine.spring.beans.factory.support.DefaultListableBeanFactory@723ca036
执行:destroy-method
执行:UserService.destroy

但是 不是很能理解为什么把beanPostProcessors放在AbstractBeanFactory里面管理

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值