mini-spring-Bean含参实例化(三)

上一节,bean是在AbstractAutowireCapableBeanFactory.doCreateBean方法中用beanClass.newInstance()来实例化,仅适用于bean有无参构造函数的情况。
本节考虑含参的bean的实例化
考虑两个问题
一、串流程从哪合理的把构造函数的入参信息传递到实例化操作里
BeanFactory 中添加 Object getBean(String name, Object… args) 接口,AbstractBeanFactory中使用doGetBean实现接口
二、怎么去实例化含有构造函数的对象。,
使用动态代理的方式实例化bean对象

新增 getBean 接口

public interface BeanFactory {

    Object getBean(String name) throws BeansException;

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

}

定义实例化策略接口

public interface InstantiationStrategy {
	/**
	 *
	 * @param beanDefinition bean定义信息
	 * @param beanName bean名称
	 * @param ctor 含了一些必要的类信息,有这个参数的目的就是为了拿到符合入参信息相对应的构造函数
	 * @param args 具体的含参信息
	 * @return
	 * @throws BeansException
	 */
//	Object instantiate(BeanDefinition beanDefinition) throws BeansException;
Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException;
}

JDK 实例化

首先通过 beanDefinition 获取 Class 信息,这个 Class 信息是在 Bean 定义的时候传递进去的。
接下来判断 ctor 是否为空(判断有没有参数信息),如果为空则是无构造函数实例化,否则就是需要有构造函数的实例化。

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) {
				//clazz.getDeclaredConstructor返回指定参数的构造器 通过类对象访问
				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);
		}
	}
}

Cglib 实例化

public class CglibSubclassingInstantiationStrategy implements InstantiationStrategy {

	/**
	 * 使用CGLIB动态生成子类
	 *
	 * @param beanDefinition
	 * @return
	 * @throws BeansException
	 */

	@Override
	public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException {
		//cglib工具类
		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);
	}
}

创建策略调用

实例化一个有参的bean

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {

	private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
	//实现创建bean
	@Override
	protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException {
		Object bean = null;
		try {
			bean = createBeanInstance(beanDefinition, beanName, args);
		} catch (Exception e) {
			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();
		for (Constructor ctor : declaredConstructors) {
			if (null != args && ctor.getParameterTypes().length == args.length) {
				constructorToUse = ctor;
				break;
			}
		}
		return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructorToUse, args);
	}

	/**
	 * 属性的get set方法
	 * @return
	 */
	public InstantiationStrategy getInstantiationStrategy() {
		return instantiationStrategy;
	}
	public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
		this.instantiationStrategy = instantiationStrategy;
	}
}

测试

定义一个类’

public class HelloService {


		private String name;

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

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

		@Override
		public String toString() {
			final StringBuilder sb = new StringBuilder("");
			sb.append("").append(name);
			return sb.toString();
		}
}
public class BeanDefinitionAndBeanDefinitionRegistryTest {

	@Test
	public void testBeanFactory() throws Exception {
		// 1.初始化 BeanFactory
		DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
		// 3. 注入bean
		BeanDefinition beanDefinition = new BeanDefinition(HelloService.class);
		beanFactory.registerBeanDefinition("helloService", beanDefinition);
		// 4.获取bean
		HelloService helloService = (HelloService) beanFactory.getBean("helloService", "我的参数");
		helloService.queryUserInfo();
	}
}