前言
咋一看标题,小伙伴们是否还有点小激动呢?觉得这怎么可能呢?
可能我们(大众)都是这样认为:自从用上了Spring这个优秀的框架,一般小伙伴们都是一言不合就把对象塞进Spring的IOC容器里面,交给它来替我们管理。
不可否认的是,把Bean交给Spring管理,确实极其的方便,优点一大把,并且还几乎没有啥缺点。这也就是为何咱们一言不合就把Bean扔给Spring的原因。(在Spring的技术栈里这么做,完全没有问题)
然而,就Spring框架本身而言。它的强大的依赖注入,不仅仅能给自家的Bean使用,还能赋能给容器之外的Bean,快速的把需要注入的对象给它装配好。
本来我也一直以为你想用Spring的依赖注入功能,就得交给Spring容器进行管理。直到我上周看AutowireCapableBeanFactory源码的时候,上面的JavaDoc就清晰的写到了,它还可以为非容器内的Bean服务~
注意:原对象可以不在Spring的IOC容器里,但是需要被依赖注入的成员,就必须是Spring容器管辖的Bean
本篇文章实际用处可能较少(可能在继承某些特殊的第三方框架的时候需要),但是掌握了本篇文章的内容,能让你更加清晰的了解到Spring依赖注入的原理(一般应用开发者不会使用这个接口,但如果你是框架设计者,你有必要了解这个接口)
我们使用的应用上下文ApplicationContext它就提供了
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
虽然它不直接继承,但是它允许你拿这个工具去做你需要的事。~~~
Spring源码基于的Spring版本为:5.0.6.RELEASE(下同)
Spring源码基于的Spring版本为:5.0.6.RELEASE(下同)
Spring源码基于的Spring版本为:5.0.6.RELEASE(下同)
AutowireCapableBeanFactory 的解释
* Extension of the {@link org.springframework.beans.factory.BeanFactory} * interface to be implemented by bean factories that are capable of * autowiring, provided that they want to expose this functionality for * existing bean instances.
AutowireCapableBeanFactory在BeanFactory基础上实现了对存在实例的管理.可以使用这个接口集成其它框架,捆绑并填充并不由Spring管理生命周期并已存在的实例.像集成WebWork的Actions 和Tapestry Page就很实用.
public interface AutowireCapableBeanFactory extends BeanFactory { int AUTOWIRE_NO = 0; int AUTOWIRE_BY_NAME = 1; int AUTOWIRE_BY_TYPE = 2; int AUTOWIRE_CONSTRUCTOR = 3; @Deprecated int AUTOWIRE_AUTODETECT = 4; // 注意这个CreateBean和下面的CrateBean的不同 //JavaDoc:It does <i>not</> imply traditional by-name or by-type autowiring of properties; // 也就是说它只管给你创建Bean,但是不管给你根据Name或者Type进行注入哦 // 当然,你可以显示在对应属性上指定@Autowired注解,让他也可以达到相同的效果 <T> T createBean(Class<T> beanClass) throws BeansException; void autowireBean(Object existingBean) throws BeansException; Object configureBean(Object existingBean, String beanName) throws BeansException; Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) throws BeansException; void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException; Object initializeBean(Object existingBean, String beanName) throws BeansException; Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException; Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException; void destroyBean(Object existingBean); <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException; @Nullable Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException; @Nullable Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException; }
这里就不解释各个方法了,具体参考:
【小家Spring】BeanFactory体系和ApplicationContext体系,两大体系各接口分析、区别和联系
Demo Show
说得可能还是一头雾水,上个例子先看看效果吧:
以createBean() 方法为例
// 准备一个Child类 @Getter @Setter public class Child { // 注意:这里并没有@Autowired注解的 private HelloService helloService; private String name; private Integer age; } public static void main(String[] args) { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(RootConfig.class); // ApplicationContext里面是持久AutowireCapableBeanFactory这个工具的,它真实的实现类一般都是:DefaultListableBeanFactory AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory(); // 我们吧Child的创建过程都交给Bean工厂去帮我们处理,自己连new都不需要了 (createBean方法执行多次,就会创建多个child实例) Child child = (Child) autowireCapableBeanFactory.createBean(Child.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false); //简直残暴,没有@Autowired注解都给注入进来了~~~ 至于为什么,看看下面的分析,你就知道了 System.out.println(child.getHelloService()); //com.fsx.service.HelloServiceImpl@6a78afa0 // 抛出异常 No qualifying bean of type 'com.fsx.bean.Child' available // 能佐证:我们的Bean并没交给Spring容器管理,它只是帮我们创建好了,并把对应属性注入进去了 Child bean = applicationContext.getBean(Child.class); System.out.println(bean); }
看到这个现象有没有很惊喜,我们哪怕不是Spring去管理的对象,都能够依赖注入进来容器内的对象,并且,并且连@Autowired注解都不需要。所以更别谈Spring内部的容器,并且还标注了注解的,那就应该更容易去实现了
所以,了解了本文后,再回过头去看看Spring内部的自动化的依赖注入,就会说一句:也就那样嘛,哈哈~
以createBean() 方法为例的源码分析
在上面Demo Show的基础上,我们来看看源码,到底是怎么做到的。
来到AbstractAutowireCapableBeanFactory#createBean:
@Override public Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException { // Use non-singleton bean definition, to avoid registering bean as dependent bean. RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck); // 这里看到了,采用的不是单例,而是prototype bd.setScope(BeanDefinition.SCOPE_PROTOTYPE); // For the nullability warning, see the elaboration in AbstractBeanFactory.doGetBean; // in short: This is never going to be null unless user-declared code enforces null. // doc说得很明白,这里返回值永远不可能为null。除非调用者强制return null // 注意的是:这里BeanName就是beanClass.getName() return createBean(beanClass.getName(), bd, null); } // 最终都调用到了下面这个createBean方法。它也是AbstractBeanFactory提供的一个抽象方法 // 最终也由AbstractAutowireCapableBeanFactory去实现的。 我们熟悉的doGetBean()方法,最终也是调用它来创建实例对象 只是doGetBean()把单例对象都缓存起来了 // 这个方法很单纯:创建一个实例,然后初始化他(给属性们赋值),然后return出去即可 @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. // 解析一些@lookup注解之类的 忽略 try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. // 这个之前都解释过了,就不解释了。若BeanPostProcessors 产生了一个代理对象,就不需要我去创建了,就不继续往下走了(AOP都走这里) Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { // 重点来了。它是本类的一个protected方法,专门用于处理创建Bean的过程(包括属性赋值之类的) Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
这里再看看doCreateBean吧,因为之前有讲过这个方法,这里就看看止看看核心步骤。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args){ BeanWrapper instanceWrapper = null; ... //createBeanInstance 是重点(都是返回一个BeanWrapper) 它也是本类的一个protected方法 instanceWrapper = createBeanInstance(beanName, mbd, args); // Bean已经实例化好了,准备初始化吧 ... // 执行MergedBeanDefinitionPostProcessor // 处理循环引用,现在若我们Bean不在容器里,肯定是不存在循环引用的(但是我依赖的Bean可能还没创建是真的,也是这里来处理的) ... // 给Bean实例的各个属性进行赋值 比如调用InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation、给属性注入值(并不依赖于@Autowired注解) // 执行InstantiationAwareBeanPostProcessor#postProcessPropertyValues等等 populateBean(beanName, mbd, instanceWrapper); // 初始化Bean 执行一些初始化方法init @PostContruct方法等等 //BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization等等 exposedObject = initializeBean(beanName, exposedObject, mbd); }
综上可以看出,目前最重要的三个步骤为doCreateBean
里面的:createBeanInstance
、populateBean
、initializeBean
,都在AbstractAutowireCapableBeanFactory
这里