您当前的位置: 首页 >  spring

java持续实践

暂无认证

  • 4浏览

    0关注

    746博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

手写spring 03 - Cglib 构造函数实例化对象

java持续实践 发布时间:2022-04-23 15:02:01 ,浏览量:4

文章目录
      • 目标
      • 设计
      • 实现
        • 新增getBean接口
        • 定义实例化策略接口
        • JDK 实例化
        • Cglib 实例化
        • 创建策略调用
      • 测试
        • 测试有参的构造实例创建
        • 测试无构造函数的
        • 测试有构造函数实例化
        • 获取构造函数信息
        • 测试Cglib实例化
        • 测试Cglib的策略实例化

目标

实现有参构造函数实例化对象.

设计

参考Spring Bean的容器源码实现方式, 在BeanFactory中添加Object getBean(String name, Object... args)

创建有参构造bean对象的两种方式

  • 基于jdk的DeclaredConstructor
  • 使用Cglib 动态创建Bean对象

uml图如下 BeanFactory 类新增getBean方法, 该方法有可变参数的构造. AbstractAutowireCapableBeanFactory 对象, 创建bean的入参改为可接收多个数组参数. 依赖创建实例的策略接口 InstantiationStrategy, 该策略接口由两个实现类 CglibSubclassInstantiationStrategy 和 SimpleInstantiationStrategy 分别是基于Cglib和jdk的创建对象.

实现 新增getBean接口
public interface BeanFactory {

    Object getBean(String name) throws BeansException;

    /**
     *  重载多参数的getBean方法  这样可以方便的传递入参给构造函数
     * @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;
}
JDK 实例化
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 (ctor != null) {
                // 有参构造的实例化
                return clazz.getDeclaredConstructor(ctor.getParameterTypes()).newInstance(args);
            } else {
                //  无参构造的实例化
                return clazz.getDeclaredConstructor().newInstance();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BeansException("failed to instantiate " + clazz.getName(), e);
        }
    }
}

判断是否为有构造函数的实例化

Cglib 实例化
public class CglibSubclassInstantiationStrategy 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 (ctor == null) {
            return enhancer.create();
        }
        return enhancer.create(ctor.getParameterTypes(), args);
    }
}
创建策略调用
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {

    private InstantiationStrategy instantiationStrategy = new CglibSubclassInstantiationStrategy();

    protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException {
        Object bean;
        try {
            // 构建对象  通过传入构造函数的入参
            bean = createBeanInstance(beanDefinition, beanName, args);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BeansException("Instantiation of bean failed", e);
        }
        addSingleton(beanName, bean);
        return bean;
    }

    protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object[] args) {
        Constructor constructorToUse = null;
        Class beanClass = beanDefinition.getBeanClass();
        // 获取到所有的构造函数
        Constructor[] declaredConstructors = beanClass.getDeclaredConstructors();
        // Constructor 代表了你有多少个构造函数
        for (Constructor ctor : declaredConstructors) {
            if (null != args && ctor.getParameterTypes().length == args.length) {
                // 循环比对出构造函数集合与入参信息 args 的匹配情况
                constructorToUse = ctor;
                break;
            }
        }
        return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructorToUse, args);
    }

    public InstantiationStrategy getInstantiationStrategy() {
        return instantiationStrategy;
    }

    public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
        this.instantiationStrategy = instantiationStrategy;
    }
}
测试

测试的业务类

public class UserService {

    private String name;

    public UserService() {
    }

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

    public void queryUserInfo() {
        System.out.println("查询用户信息: " + name);
    }

    @Override
    public String toString() {
        return "UserService{" +
                "name='" + name + '\'' +
                '}';
    }
}
测试有参的构造实例创建
  @Test
    public void test_BeanFactory() {
        // 1.初始化 BeanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

        // 3. 注入bean
        BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
        beanFactory.registerBeanDefinition("userService", beanDefinition);

        // 4.获取bean  创建对象 传递有参数的
        UserService userService = (UserService) beanFactory.getBean("userService", "周杰伦");
        userService.queryUserInfo();
    }

测试结果如下

查询用户信息: 周杰伦

测试无构造函数的
 /**
     *  无参构造创建对象
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    @Test
    public void test_noArgsNewInstance() throws IllegalAccessException, InstantiationException {
        UserService userService = UserService.class.newInstance();
        System.out.println(userService);  // UserService{name='null'}
    }
测试有构造函数实例化
 /**
     * 有参构造创建对象
     * @throws Exception
     */
    @Test
    public void test_constructor() throws Exception {
        Class userServiceClass = UserService.class;
        Constructor declaredConstructor = userServiceClass.getDeclaredConstructor(String.class);
        UserService userService = declaredConstructor.newInstance("周杰伦");
        System.out.println(userService); // UserService{name='周杰伦'}
    }
获取构造函数信息
 @Test
    public void test_parameterTypes() throws Exception {
        Class beanClass = UserService.class;
        Constructor[] declaredConstructors = beanClass.getDeclaredConstructors();
        Constructor constructor = null;

        for (Constructor ctor : declaredConstructors) {
            if (ctor.getParameterTypes().length == 1) {
                constructor = ctor;
                break;
            }
        }
        Constructor declaredConstructor = beanClass.getDeclaredConstructor(constructor.getParameterTypes());
        UserService userService = declaredConstructor.newInstance("周杰伦");
        System.out.println(userService);  // UserService{name='周杰伦'}
    }
测试Cglib实例化
 @Test
    public void test_cglib() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(UserService.class);
        enhancer.setCallback(new NoOp() {
            @Override
            public int hashCode() {
                return super.hashCode();
            }
        });
        Object obj = enhancer.create(new Class[]{String.class}, new Object[]{"周杰伦"});
        System.out.println(obj);  // UserService{name='周杰伦'}
    }
测试Cglib的策略实例化
@Test
    public void test_cglibSubclassInstantiationStrategy() throws Exception {
        InstantiationStrategy instantiationStrategy = new CglibSubclassInstantiationStrategy();
        BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
        Class userServiceClass = UserService.class;
        Constructor declaredConstructor = userServiceClass.getDeclaredConstructor(String.class);

        Object obj = instantiationStrategy.instantiate(beanDefinition, "userService" , declaredConstructor, new Object[]{"周杰伦"});
        System.out.println(obj);  // UserService{name='周杰伦'}
    }
关注
打赏
1658054974
查看更多评论
立即登录/注册

微信扫码登录

0.1539s