我们一路往下跟进resolveDependency()我们关注这个方法如下代码:
if (instanceCandidate instanceof Class) {// todo !!!!!当运行到这行代码时, myService还没有被实例化(singletonObjects中没有) 执行完这一个行代码之后, IndexDao1完成了对myService的装配 instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this); }跟进这个resolveCandidate()源码如下:
很直接发现,出现的递归的现象,这其实解析清楚了Spring是如何完成属性注入的,就是只不过前前后后很多接口很多类,会扰乱这个阅读的过程
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) throws BeansException { // todo 从bean工厂的获取, beanName = myService requiredType = com.changwu...OrderService2 , 跟进去这个方法, 他调用了AbstractBeanFactory中的getBean(){ doGetBean();} return beanFactory.getBean(beanName); }完成装配后,其实现在的对象依然是原生的java对象 回到AbstractAutowireCapableBeanFactory中的initializeBean()方法,源码如下, 看了下面的代码就是知道了为什么applyBeanPostProcessorsBeforeInitialization和init()和applyBeanPostProcessorsAfterInitialization()之间的调用顺序了
还有最后一个秘密需要揭开: Spring的AOP不是产生了代理对象? 那什么时候完成的代理呢?毕竟从我开始写这篇文章到最后都没有看到,其实AOP的实现就在下面的代码中
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //todo 执行全部的后置处理器的 Before方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // todo 执行所有的init方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // todo 执行所有的后置处理器的 after方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }我们在前面知道当遇到这个AbstractAutoProxyCreator时,回调它的before()方法时,仅仅是标记哪些对象需要进行增强哪些对象不需增强,而没有立即生成代理对象
现在我们关注这行代码 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); ,生成代理对象的逻辑就在这里面
@Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { // todo 进入 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }看这个方法wrapIfNecessary(bean, beanName, cacheKey);最终会进入这个实现中
大家可以看到Spring为bean生成了代理对象,默认会先检查被代理的对象有没有实现接口,如果实现了接口,就是用jdk动态代理,否则就看看有没有cglib的相关依赖,如果存在的相关依赖而没有实现接口,就会使用cglib的代理模式
另外,补充通过编码的方式控制 下面的if条件
config.isOptimize() -> 可以通过XMl配置, 默认false
config.isProxyTargetClass() -> @EnableAspectjAutoPeoxy(true) 默认也是false
@SuppressWarnings("serial") public class DefaultAopProxyFactory implements AopProxyFactory, Serializable { @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { //todo 目标对象是一个接口, 同样是使用jdk的动态代理 return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { // todo 所以默认使用的是 jdk的动态代理 return new JdkDynamicAopProxy(config); } } 公众号首发、欢迎关注