package cn.noexception.container.factory.support; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.StrUtil; import cn.noexception.container.BeansException; import cn.noexception.container.PropertyValue; import cn.noexception.container.PropertyValues; import cn.noexception.container.factory.*; import cn.noexception.container.factory.config.*; import java.lang.reflect.Constructor; import java.lang.reflect.Method; /** * AbstractAutowiredCapableBeanFactory * * @author 吕滔 * @Date 2021/10/22 17:46 */ public abstract class AbstractAutowiredCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); // 暂时默认选择 cglib 来实例化 @Override protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { Object bean = null; try { // 判断是否返回代理Bean对象 bean = resolveBeforeInstantiation(beanName, beanDefinition); if (null != bean) { return bean; } // 实例化 Bean bean = createBeanInstance(beanDefinition, beanName, args); // 在设置 Bean 属性之前,允许 BeanPostProcessor 修改属性值 applyBeanPostProcessorsBeforeApplyingPropertyValues(beanName, bean, beanDefinition); // 给 Bean 填充属性值 applyPropertyValues(beanName, bean, beanDefinition); // 执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法 bean = initializeBean(beanName, bean, beanDefinition); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } // 注册实现了 DisposableBean 接口的 Bean 对象 registerDisposableBeanIfNecessary(beanName, bean, beanDefinition); // 判断 SCOPE_SINGLETON、SCOPE_PROTOTYPE if (beanDefinition.isSingleton()) { registerSingleton(beanName, bean); } return bean; } /** * 在设置 Bean 属性之前,允许 BeanPostProcessor 修改属性值 * * @param beanName * @param bean * @param beanDefinition */ protected void applyBeanPostProcessorsBeforeApplyingPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) { for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) { if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { PropertyValues pvs = ((InstantiationAwareBeanPostProcessor) beanPostProcessor).postProcessPropertyValues(beanDefinition.getPropertyValues(), bean, beanName); if (null != pvs) { for (PropertyValue propertyValue : pvs.getPropertyValues()) { beanDefinition.getPropertyValues().addPropertyValue(propertyValue); } } } } } protected Object resolveBeforeInstantiation(String beanName, BeanDefinition beanDefinition) { Object bean = applyBeanPostProcessorsBeforeInstantiation(beanDefinition.getBeanClass(), beanName); if (null != bean) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } return bean; } protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName) { for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) { if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { Object result = ((InstantiationAwareBeanPostProcessor) beanPostProcessor).postProcessBeforeInstantiation(beanClass, beanName); if (null != result) return result; } } return null; } protected void registerDisposableBeanIfNecessary(String beanName, Object bean, BeanDefinition beanDefinition) { // 非 Singleton 类型的 Bean 不执行销毁方法 if (!beanDefinition.isSingleton()) return; if (bean instanceof DisposableBean || StrUtil.isNotEmpty(beanDefinition.getDestroyMethodName())) { registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, beanDefinition)); } } protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object[] args) { Constructor constructorToUse = null; Class beanClass = beanDefinition.getBeanClass(); Constructor[] declaredContructors = beanClass.getDeclaredConstructors(); for (Constructor ctor : declaredContructors) { if (null != args && ctor.getParameterTypes().length == args.length) { constructorToUse = ctor; break; } } return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructorToUse, args); } /** * 属性填充 */ protected void applyPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) { try { PropertyValues propertyValues = beanDefinition.getPropertyValues(); for (PropertyValue propertyValue : propertyValues.getPropertyValues()) { String name = propertyValue.getName(); Object value = propertyValue.getValue(); if (value instanceof BeanReference) { // A 依赖 B,获取 B 的实例化 BeanReference beanReference = (BeanReference) value; value = getBean(beanReference.getBeanName()); } // 属性填充 BeanUtil.setFieldValue(bean, name, value); } } catch (Exception e) { throw new BeansException("Error setting property values: " + beanName); } } public InstantiationStrategy getInstantiationStrategy() { return instantiationStrategy; } public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) { this.instantiationStrategy = instantiationStrategy; } private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) { // invokeAwareMethods if (bean instanceof Aware) { if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(this); } if (bean instanceof BeanClassLoaderAware) { ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); } if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } } // 1. 执行 BeanPostProcessor Before 处理 Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName); try { invokeInitMethods(beanName, wrappedBean, beanDefinition); } catch (Exception e) { throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", e); } // 2. 执行 BeanPostProcessor After 处理 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); return wrappedBean; } private void invokeInitMethods(String beanName, Object bean, BeanDefinition beanDefinition) throws Exception { // 1. 实现接口 InitializingBean if (bean instanceof InitializingBean) { ((InitializingBean) bean).afterPropertiesSet(); } // 2. 配置信息 init-method (判断是为了避免二次执行销毁) String initMethodName = beanDefinition.getInitMethodName(); if (StrUtil.isNotEmpty(initMethodName)) { Method initMethod = beanDefinition.getBeanClass().getMethod(initMethodName); if (null == initMethod) { throw new BeansException("Could not find an init method named '" + initMethodName + "' on bean with name '" + beanName + "'"); } initMethod.invoke(bean); } } @Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (null == current) return result; result = current; } return result; } @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (null == current) return result; result = current; } return result; } }