学习笔记-Spring实战-动手实现一个小的spring-Chapter-3

本文探讨了如何在Spring框架中实现带参数的构造函数注入,并通过具体代码演示了使用CGLIB代理技术来创建带有参数的Bean实例的过程。

学习笔记-Spring实战-动手实现一个小的spring-Chapter-3

1、思考

怎么处理带参数的构造函数呢?
传入,可以在获取Bean的时候把参数传入,BeanFactory的getBean方法 getBean(String name,Object …args);
怎么创建带参实例?两种 jdk反射 cglib代理技术
在那边写代码呢?(串流程)可以在创建Bean的时候 AbstractAutowireCapableBeanFactory这个里面加入逻辑

2、设计

在这里插入图片描述

3、实现

1、BeanFactory:

/**
 *
 * @param beanname
 * @param args
 * @return java.lang.Object
 * @author LiWenQiang
 * @date 2022/3/3 09:40
 */
Object getBean(String beanname,Object... args);

2、AbstractBeanFactory

@Override
public Object getBean(String beanName) {
    //整合在一起
    return doGetbean(beanName,null);

}
@Override
public Object getBean(String beanName, Object... args) {
    return doGetbean(beanName,args);
}

protected Object doGetbean(String beanName,Object ...args){
    //判断是否存在bean
    final Object singleton = getSingleton(beanName);
    if(singleton != null){
        return singleton;
    }
    //获取bean定义
    final BeanDefinition beanDefinition = getBeanDefinition(beanName);
    return createBean(beanName,beanDefinition,args);
}

abstract protected  Object createBean(String beanName, BeanDefinition beanDefinition,Object ... args);

3、AbstractAutowiredCapableBeanFactory

InstantiationStrategy instantiationStrategy = new CglibInstantionStategy();


@Override
protected Object createBean(String beanName, BeanDefinition beanDefinition, Object... args) {

    Object bean = null;
    //创建Bean
    try {
        bean = createBeanInstance(beanName,beanDefinition,args);
    } catch (Exception e) {
        //转换异常 并把原始异常抛出
        throw new BeansException("bean create fail!",e);
    }
    //加入到容器
    adddSingleton(beanName,bean);
    return bean;

}

protected Object createBeanInstance(String beanName, BeanDefinition beanDefinition, Object[] args) {
    final Constructor<?>[] declaredConstructors = beanDefinition.getBeanDefinition().getDeclaredConstructors();
    Constructor c = null;
    for (Constructor<?> declaredConstructor : declaredConstructors) {
        if(args != null && declaredConstructor != null && declaredConstructor.getParameterTypes().length==args.length){
            c = declaredConstructor;
            break;
        }
    }
    final Object beanInstance = getInstantiationStrategy().createBeanInstance(beanName, beanDefinition, c, args);
    return beanInstance;
}

public InstantiationStrategy getInstantiationStrategy() {
    return instantiationStrategy;
}

4、InstantiationStrategy

Object createBeanInstance(String beanName, BeanDefinition beanDefinition, Constructor constructor,Object ... args) throws BeansException;

5、CglibInstantionStategy

@Override
public Object createBeanInstance(String beanName, BeanDefinition beanDefinition, Constructor constructor, Object... args) throws BeansException {
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(beanDefinition.getBeanDefinition());
    enhancer.setCallback(new NoOp() {
        @Override
        public int hashCode() {
            return super.hashCode();
        }
    });
    if(constructor != null){
        return enhancer.create(constructor.getParameterTypes(),args);
    }
    return enhancer.create();
}

4、验证

@Test
public void testIOC1(){
    //创建IOC容器
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

    //注册一个bean进去
    beanFactory.registBeanDefinition("userService",new BeanDefinition(UserService.class));

    //获取bean 多次获取
    final UserService userService = (UserService) beanFactory.getBean("userService","111");
    final UserService userService2 = (UserService) beanFactory.getBean("userService","222");
    final UserService userService3 = (UserService) beanFactory.getBean("userService","333");

    System.out.println(userService);
    System.out.println(userService2);
    System.out.println(userService3);

    //调用方法测试
    userService.queryUserInfo();
}

5、问题

现在注册的Bean都是没有属性的?Bean的属性怎么填充呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值