上一节,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 {@Overridepublic 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*/@Overridepublic 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() {@Overridepublic 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@Overrideprotected 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);}@Overridepublic String toString() {final StringBuilder sb = new StringBuilder("");sb.append("").append(name);return sb.toString();}
}
public class BeanDefinitionAndBeanDefinitionRegistryTest {@Testpublic void testBeanFactory() throws Exception {// 1.初始化 BeanFactoryDefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();// 3. 注入beanBeanDefinition beanDefinition = new BeanDefinition(HelloService.class);beanFactory.registerBeanDefinition("helloService", beanDefinition);// 4.获取beanHelloService helloService = (HelloService) beanFactory.getBean("helloService", "我的参数");helloService.queryUserInfo();}
}