上一节,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(); } }