36.解析BeanDefinition

73 阅读15分钟

FactoryBean接口示例代码

public interface FactoryBean<T> {   
    @Nullable
    T getObject() throws Exception;
 
    @Nullable
    Class<?> getObjectType();
 
    default boolean isSingleton() {
        return true;
    }
}

所谓的Smart就是多了2个方法。

isPrototype默认返回值是false也就是默认是单例!

isEagerInit默认返回值是false也就是默认是懒加载!

public interface SmartFactoryBean<T> extends FactoryBean<T> {
 
    default boolean isPrototype() {
        return false;
    }
​
    default boolean isEagerInit() {
        return false;
    }
​
}
​

示例代码

package factoryBean;
​
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.SmartFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Description;
import org.springframework.stereotype.Component;
​
//为了方便测试可以先注释掉
@Component
@Description("业务类")
public class UserFactoryBean implements SmartFactoryBean {
​
    public UserFactoryBean() {
        System.out.println("UserFactoryBean");
    }
​
    private int age = 31;
    private String name;
​
    public int getAge() {
        return age;
    }
​
    public void setAge(int age) {
        this.age = age;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    @Override
    public Object getObject() throws Exception {
        System.out.println("getObject");
        return new  User();
    }
​
    @Override
    public Class<?> getObjectType() {
        return User.class;
    }
​
    @Override
    public boolean isEagerInit() {
        return true;
    }
}
package factoryBean;
​
public class User {
}
package factoryBean;
​
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
​
@Configuration
@ComponentScan("factoryBean")
public class Config {
    public Config() {
        System.out.println("------------------------Config实例化了");
    }
}
​
package factoryBean;
​
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
​
public class ParseTest {
    public static void main(String[] args) throws Exception {
        start1();
    }
    
     public static void start1() throws Exception {
        //其中Config.class可以指定为
        //包扫描启动:@ComponentScan("tyrant")
        //使用xml文件启动:@ImportResource("applicationContext.xml")
        AnnotationConfigApplicationContext context 
                        = new AnnotationConfigApplicationContext();
         //注册配置类
        context.register(Config.class);
        context.refresh();
​
        //生成&userFactoryBean的时候会去掉&
        //放在一级缓存的是1个 UserFactoryBean
        //根据 &userFactoryBean 获取的时候 会先判断是否以&开头如果是
        //那么直接返回的是UserFactoryBean 
        UserFactoryBean userFactoryBean = 
                (UserFactoryBean)context.getBean("&userFactoryBean");
        
        //生成
        User user1 = (User)context.getBean("userFactoryBean");
        User user2 = (User)context.getBean("userFactoryBean");
        System.out.println(user1==user2);
     }
}

生成FactoryBean

@Override
    public void preInstantiateSingletons() throws BeansException {
         
        /***
         * 放置所有bean的name
         */
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
​
        /***
         * 循环所有需要创建的beanName 依次创建bean
         */
        for (String beanName : beanNames) {
            //获取合并的bd
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            /***
             * 非抽象 && 单例 && 非懒加载
             */
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                //判断是否实现了FactoryBean接口
                //如果实现了FactoryBean接口 那么需要先创建FactoryBean接口的实现类
                //bean的名称是真正的beanName
                if (isFactoryBean(beanName)) {
                    //这里虽然用&+beanName做了拼接
                    //但是在getBean方法中会先去掉&然后去创建FactoryBean接口的实现类
                    //然后放入1级缓存
                    //key为 userFactoryBean
                    //value 为 UserFactoryBean对象
                    //注意这里是第一次调用getBean 在这里创建的是UserFactoryBean对象
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    //判断是否是Factory
                    if (bean instanceof FactoryBean) {
                        FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null
                                    && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged(
                                (PrivilegedAction<Boolean>) 
                                ((SmartFactoryBean<?>) factory)::isEagerInit,
                                getAccessControlContext());
                        }else {
                            //如果是SmartFactoryBean类型
                            //且SmartFactoryBean的isEagerInit()返回的是true
                            isEagerInit = (factory instanceof SmartFactoryBean 
                                &&((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        //是否立即加载 如果是立即加载 那么开始创建bean
                        //在bean非懒加载情况下 
                        //会立刻使用getBean方法创建FactoryBean生成的Bean
                        //getBean首先从1级缓存查找
                        //获取到的对象是UserFactoryBean对象
                        //进入方法getObjectForBeanInstance
                        if (isEagerInit) {
                            //FactoryBean走这里 创建bean入口
                            //在这里创建的是FactoryBean的getObject方法返回的对象
                            //调用getObejct方法返回的对象
                            //会被放在工厂的1个Map属性:factoryBeanObjectCache里
                            getBean(beanName);
                        }
                    }
                }else {
                    //非FactoryBean走这里
                    getBean(beanName);
                }
            }
        }
​
    }
@SuppressWarnings("unchecked")
    protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, 
        @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {
        //解析bean 如果以&开头 去掉& 如果是别名获取真正的名字
        String beanName = transformedBeanName(name);
        Object bean;
        
        //第一次调用getBean会走else 创建的是UserFactoryBean对象
        //第二次调用getBean会从缓存中获取到UserFactoryBean对象
        
        //从缓存中获取
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            /***
             * 如果实现了FactoryBean接口 需要获取具体对象 要使用下面的方法进行获取
             * 如果没有实现FactoryBean接口 会直接返回传递进来的beanInstance
             * 这里需要注意传入的beanName是不带& name是带&的
             */
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        } else {
            sharedInstance = getSingleton(beanName, () -> {
                try {
                    return createBean(beanName, mbd, args);
                } catch (BeansException ex) {
                    destroySingleton(beanName);
                    throw ex;
                }
            });
            /***
             如果实现了FactoryBean接口 需要获取具体对象 要使用下面的方法进行获取
             如果没有实现FactoryBean接口 会直接返回传递进来的beanInstance
            */
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
        }
        return (T) bean;
    }
protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {


		//如果name是以&开头即获取的是FactoryBean接口的实现类
		if (BeanFactoryUtils.isFactoryDereference(name)) {
			//如果是NullBean 直接返回
			if (beanInstance instanceof NullBean) {
				return beanInstance;
			}
			//进了这个方法beanInstance必须是实现了FactoryBean接口
			//否则抛出异常
			if (!(beanInstance instanceof FactoryBean)) {
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
		}

		//如果不是FactoryBean类型 或者	以&开头 才会进入判断。
    	//beanInstance是UserFactoryBean
		//情况1:name = &userFactoryBean
		//beanInstance不是FactoryBean -->false
		//&userFactoryBean是以&开头 -->true
		//直接返回beanInstance 也就是1级缓存中的对象!

		//情况2:name = userFactoryBean
		//beanInstance不是FactoryBean -->false
		//userFactoryBean是以&开头 -->false
		//继续往下走
    	//如果没有实现FactoryBean接口或者以&开头 直接返回bean
		if (!(beanInstance instanceof FactoryBean) || 
            		BeanFactoryUtils.isFactoryDereference(name)) {
			
			return beanInstance;
		}

		//进入了这里说明一定是FactoryBean 并且要拿Factory生产的对象
		Object object = null;
		if (mbd == null) {
			//从缓存中获取 说明肯定是实例化好以后放入了factoryBeanObjectCache
			//return this.factoryBeanObjectCache.get(beanName);
			object = getCachedObjectForFactoryBean(beanName);
		}
		//第一次从缓存拿是空对象
		if (object == null) {
			// Return bean instance from factory.
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			if (mbd == null && containsBeanDefinition(beanName)) {
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			//从Factory中获取
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

单例多例控制

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
		//单例放缓存
		if (factory.isSingleton() && containsSingleton(beanName)) {
			synchronized (getSingletonMutex()) {
				Object object = this.factoryBeanObjectCache.get(beanName);
				if (object == null) {
					object = doGetObjectFromFactoryBean(factory, beanName);
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
						object = alreadyThere;
					}
					else {
						if (shouldPostProcess) {
							if (isSingletonCurrentlyInCreation(beanName)) {
								return object;
							}
							beforeSingletonCreation(beanName);
							try {
								//生成代理对象
								object = postProcessObjectFromFactoryBean
                                    						(object, beanName);
							}
							catch (Throwable ex) {
								throw new BeanCreationException
                                  (beanName,"PostProcessFactoryBean's object failed");
							}
							finally {
								afterSingletonCreation(beanName);
							}
						}
						//Factory是单例多例都是由这个方法控制
						//单例放缓存
						//多例则每次都创建新对象
						if (containsSingleton(beanName)) {
							this.factoryBeanObjectCache.put(beanName, object);
						}
					}
				}
				return object;
			}
		}
		//多例则每次都创建新对象
		else {
			Object object = doGetObjectFromFactoryBean(factory, beanName);
			if (shouldPostProcess) {
				try {
					object = postProcessObjectFromFactoryBean(object, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException
                       (beanName, "Post-processing of FactoryBean's object failed", ex);
				}
			}
			return object;
		}
	}

@Bean修饰的方法示例代码

package parse;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
public class Config {
	public Config() {
		System.out.println("------------------------Config实例化了");
	}

	@Bean
	public  User getUser(){
		  return new User();
	}
}
package parse;

import org.springframework.context.annotation.DeferredImportSelector;
import org.springframework.context.annotation.Description;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.stereotype.Component;
//为了方便测试可以先注释掉
//@Component
@Description("业务类")
public class User implements DeferredImportSelector {
    private int age =31;
    private String name;

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
		String name = ImportedByUser.class.getName();
		return new String[]{name};
	}
}
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;

public class ParseTest {
    public static void main(String[] args) throws InterruptedException {
        start1();
    }
    
     public static void start1() {
		//其中Config.class可以指定为
        //包扫描启动:@ComponentScan("tyrant")
        //使用xml文件启动:@ImportResource("applicationContext.xml")
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		 //注册配置类
		context.register(Config.class);
		context.refresh();
		 User config = (User) context.getBean("user");
		Object user = context.getBean("getUser");
        //返回true 
		System.out.println(config.getUser() == user);
         //为什么要用代理呢?
         //原因是获取user的方式有2种
         //1.config.getUser()
         //2.context.getBean("getUser");
         //如果是单例模式 2种方式返回的对象不一样 那不就有问题吗?!
	 }

}

@Bean代理

老规矩,首先祭出我们的配置类

@ComponentScan("com.app")
@Configuration
public class Config {
}

启动spring

public class SpringTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = 
            		new AnnotationConfigApplicationContext();
        context.register(Config.class);
        context.refresh();
        System.out.println(context.getBean(Config.class));
    }
}

spring启动后,我们获取Config配置对象,打印结果如下:

img

com.config.ConfigEnhancerBySpringCGLIBEnhancerBySpringCGLIBefc56a4d@33e5ccce不言而喻,Conifg被CGLIB动态代理成了另一个增强型的对象。

我们看,Config类上有个@Configuration注解,这个注解的作用前面文章讲过好多了,表示这是一个配置类,spring扫描注册的时候会解析这个类,但是如果把这个注解去掉,我们看一下打印结果:

img

此时,spring就没有对它进行动态代理了。其实,Configuration的作用远不止如此,我们继续测试。 首先生成两个业务类E和F

public class E {
}
public class F {
}

通过@Bean方式注入

@ComponentScan("com.app")
@Configuration
public class Config {

    @Bean
    public E getE(){
        System.out.println("get class E");
        return new E();
    }
    @Bean
    public F getF(){
        getE();
        System.out.println("get class F");
        return new F();
    }
}

getE方法会生成E类的实例对象,getF方法在生成F实例对象的同时,会再一次调用getE方法生成一个E实例对象,会吗?

public class SpringTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(Config.class);
        context.refresh();
        System.out.println(context.getBean(E.class));
        System.out.println(context.getBean(F.class));
    }
}

打印结果:

img

getE在整个过程中,只被调用了一次,换句话讲,getE()方法在getF()中并没有起作用!好神奇!如果去掉@Configuration这个注解,情况就不一样了,读者可自行测试。

spring是怎么判断Config是否需要代理的呢?

context.refresh()完成了启动过程,跟进代码找到invokeBeanFactoryPostProcessors(beanFactory);,继续跟进,第一行PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());,invokeBeanFactoryPostProcessors这个方法就是调用各种后置处理器的,前面博文也讲过太多了,这里不再详述,如果读者看到这里有点懵的话,建议按顺序阅读本专题。继续,ConfigurationClassPostProcessor完成了扫描注册,完事找到方法里这么一行代码

invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

这行代码跟进去,看下源码

    private static void invokeBeanFactoryPostProcessors(
            Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

        for (BeanFactoryPostProcessor postProcessor : postProcessors) {
            postProcessor.postProcessBeanFactory(beanFactory);
        }
    }

假设我们程序员没有提供后置处理器的话,这里的postProcessors只有一个,就是ConfigurationClassPostProcessor,怎么老是这个后置处理器,这个类实现了BeanDefinitionRegistryPostProcessor接口,而BeanDefinitionRegistryPostProcessor接口又继承了BeanFactoryPostProcessor接口,ConfigurationClassPostProcessor通过BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法完成了扫描注册,spring紧接着调用ConfigurationClassPostProcessor所实现BeanFactoryPostProcessor接口的postProcessBeanFactory方法完成后续处理,这个后续处理就是上面的源码啦!

源码很简单,就是调用了后置处理器的postProcessBeanFactory方法,在这里就是ConfigurationClassPostProcessor的postProcessBeanFactory方法,我们看下它的源码

    /**
     * Prepare the Configuration classes for servicing bean requests at runtime
     * by replacing them with CGLIB-enhanced subclasses.
     * 准备配置类以便在运行时为bean请求提供服务,方法是用cglib增强的子类替换它们
     *	也就是使用cglib的代理的方式增强beanDefinition。
     */
    @Override
    public void postProcessBeanFactory
    				(ConfigurableListableBeanFactory beanFactory) {
        int factoryId = System.identityHashCode(beanFactory);
        if (this.factoriesPostProcessed.contains(factoryId)) {
            throw new IllegalStateException
                ("postProcessBeanFactory already"+
               					"called on this post-processor against ");
        }
        this.factoriesPostProcessed.add(factoryId);
        //如果有BD未解析 继续解析
        if (!this.registriesPostProcessed.contains(factoryId)) {
            //可以看到这里还在解析BD
            processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
        }
        enhanceConfigurationClasses(beanFactory);
        beanFactory
            .addBeanPostProcessor
            	(new ImportAwareBeanPostProcessor(beanFactory));
    }

前面是对当前beanDefinitionRegister做判断,是否已经处理过和注册过,不出意外的话就会进入enhanceConfigurationClasses(beanFactory);

这个方法顾名思义,就是增强配置类。

这也解释了为什么前面的Config加上@Configuration就会被动态代理。

那么下面的重点就是阅读enhanceConfigurationClasses的源码喽。

源码首先找出所有的带有@Configuration注解的配置类然后做判断

1.必须是抽象BeanDefinition

2.不能在单例池已经被创建

并存放到LinkedHashMap集合中。在这里只有咱们的Config配置类符合,然后遍历集合进行增强处理。

public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
    	
		Map<String, AbstractBeanDefinition> configBeanDefs = 
             										new LinkedHashMap<>();
    	
		for (String beanName : beanFactory.getBeanDefinitionNames()) {
			BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
            //如果配置类是FULL
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
                //如果不是抽象BD 抛出异常
				if (!(beanDef instanceof AbstractBeanDefinition)) {
                    //Cannot enhance @Configuration bean definition
                    //since it is not stored in an 			
                    // AbstractBeanDefinitionsubclass
					throw new BeanDefinitionStoreException();
				}
				else if (beanFactory.containsSingleton(beanName)) {
				// Cannot enhance @Configuration bean definition 
				// since its singleton instance has been created too early. 
                // The typical cause is a non-static @Bean method with a 		
                // BeanDefinitionRegistryPostProcessor  
				// return type: Consider declaring such methods as static
				}
				configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
			}
		}
		if (configBeanDefs.isEmpty()) {
			// nothing to enhance -> return immediately
			return;
		}

		ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
		for (Map.Entry<String, AbstractBeanDefinition> entry : 
             								configBeanDefs.entrySet()) {
            //前面已经做过InstanceOf判断 这里直接取出来
			AbstractBeanDefinition beanDef = entry.getValue();
			// If a @Configuration class gets proxied, always proxy the target class
			beanDef.setAttribute
                (AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
			try {
				// Set enhanced subclass of the user-specified bean class
				Class<?> configClass = 	
                    		beanDef.resolveBeanClass(this.beanClassLoader);
				if (configClass != null) {
                    //重点方法
					Class<?> enhancedClass = 
                        	enhancer.enhance(configClass, this.beanClassLoader);
					if (configClass != enhancedClass) {
						 //使用创建的增强classs替换原来的配置类的class
						beanDef.setBeanClass(enhancedClass);
					}
				}
			}
			catch (Throwable ex) {
					throw new IllegalStateException
                		("Cannot load configuration class");
			}
		}
	}

首先,根据BeanDefinition获取对应的class对象

Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);

然后就是增强处理:

Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);

下一个分析enhance方法看如何增强的

public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
        if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
            return configClass;
        }
    	
        Class<?> enhancedClass = createClass
            		(newEnhancer(configClass, classLoader));
        return enhancedClass;
    }

看这个方法的注释,加载指定的类并生成一个CGLIB代理的子类。

源码最重要的一行 Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));

首先分析newEnhancer方法:

    /**
     * Creates a new CGLIB {@link Enhancer} instance.
     */
    private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
        Enhancer enhancer = new Enhancer();
        //把业务类,这里是Config,设置成代理类的父类
        enhancer.setSuperclass(configSuperClass);
        //代理类实现EnhancedConfiguration接口
        enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
        enhancer.setUseFactory(false);
        //设置代理类名称的生成策略
        enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
        enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
        enhancer.setCallbackFilter(CALLBACK_FILTER);
        enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
        return enhancer;
    }

看注释,生成一个CGLIB代理实例,里面用到了Enhancer ,不就是文章开头讲的那个小demo吧! 然后就是createClass方法:

    private Class<?> createClass(Enhancer enhancer) {
        //创建配置类的子类 也就是代理类
        Class<?> subclass = enhancer.createClass();
		//注册方法拦截器
        Enhancer.registerStaticCallbacks(subclass, CALLBACKS);
        return subclass;
    }

通过Enhancer生成一个被代理类config的子类,也就是代理类。

代理结束后返回,一直返回到enhanceConfigurationClasses方法的Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);,

这时候的enhancedClass 就是代理类了,OK,这行代码执行完后往下执行了beanDef.setBeanClass(enhancedClass);,

意思很明朗,就是将Config的BeanDefinitino中的class替换成代理class。

之后就会实例化代理类而不是Config类本身。

现在解释清楚了,为什么Config加上@Configuration注解后就会被spring动态代理。再解释上文getE()方法在getF()中并没有起作用!

很明显,spring既然代理了Config,那么执行getF方法时不是真的执行Config里的getF方法,而是执行代理类的getF方法,在哪里执行的呢?

newEnhancer方法中,有一个过滤器的设置

enhancer.setCallbackFilter(CALLBACK_FILTER);

CALLBACK_FILTER是一个变量:

    private static final Callback[] CALLBACKS = new Callback[] {
            new BeanMethodInterceptor(),
            new BeanFactoryAwareMethodInterceptor(),
            NoOp.INSTANCE
    };

    private static final ConditionalCallbackFilter CALLBACK_FILTER = new ConditionalCallbackFilter(CALLBACKS);

文章一开始举的CGLIB案例中,就是通过回调完成了方法的拦截对吧?

这里有两个回调类BeanMethodInterceptor和BeanFactoryAwareMethodInterceptor。

他俩组成了一个回调链,依次调用而已。

这两个回调其实是在bean的生命周期过程中调用的,这是后续章节的内容,这里我们简单讲下,后面会详细讲。

在实例化过程中,我们主要关注BeanMethodInterceptor这个回调。

我们在调用getF方法时,会先执行回调BeanMethodInterceptor中的intercept方法。intercept方法很复杂很复杂,大概意思是,在执行getF中的getE方法时判断getE返回的bean是否已经实例化了,如果已经实例化了就不再调用该方法了。

getF和getE调用的时候都是先调用回调函数的,都会判断是否已经实例化了。

spring以此保证@Bean返回的实例是单例的。

本篇讲的比较简单比较浅,估计读者也是明白个大概的原理,因为这里涉及到后续的知识,没关系,后面会再详细讲解的。

这里大家主要了解

  1. CGLIB的使用
  2. Spring是如何利用到CGLIB的
  3. 如何使用内置的代理回调类BeanMethodInterceptor、BeanFactoryAwareMethodInterceptor来增强我们的目标类方法的即可。
  4. BeanDefinition将对应的class用代理类替换掉业务类,后期实例化的是代理类

解析BeanDefinition

递归解析配置类的内部类

private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
		//找到内部类,因为内部类也可能是一个配置类
		Collection<SourceClass> memberClasses = sourceClass.getMemberClasses();
		if (!memberClasses.isEmpty()) {
			List<SourceClass> candidates = new ArrayList<>(memberClasses.size());
			for (SourceClass memberClass : memberClasses) {
				//判断内部类是不是配置类,上文讲过了如何判断是不是配置类
				if (ConfigurationClassUtils.isConfigurationCandidate
                    (memberClass.getMetadata()) &&
						!memberClass.getMetadata().getClassName().equals
                    (configClass.getMetadata().getClassName())) {
                    //放入候选集合
					candidates.add(memberClass);
				}
			}
			//对配置类进行那个排序,上文也讲过了
			OrderComparator.sort(candidates);
			//1)出现配置类循环导入,直接报错
			for (SourceClass candidate : candidates) {

				if (this.importStack.contains(configClass)) {
					this.problemReporter.error
                        (new CircularImportProblem(configClass, this.importStack));
				}
				else {
					//将配置类入栈
					this.importStack.push(configClass);
					try {
						// 递归调用processConfigurationClass方法,也许内部类还有内部类
						//其实,工作中我们不会内部类嵌套内部类再嵌套内部类再嵌套。。。
						processConfigurationClass
                            	(candidate.asConfigClass(configClass));
					}
					finally {
						//解析完出栈
						this.importStack.pop();
					}
				}
			}
		}
	}

递归处理@CompentScan

		// Process any @ComponentScan annotations
		// 获取配置类上的@ComponentScan注解属性
		Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);

		if (!componentScans.isEmpty() &&
				!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
			for (AnnotationAttributes componentScan : componentScans) {
				// The config class is annotated with @ComponentScan 
                // -> perform the scan immediately
				//构造一个Classpath扫描器 
                //注册了1个类型过滤器@Component,@Component包含 @Controller @Repository @Service
				// 获取并解析BasePackage属性 获取需要扫描的包
				// 然后根据classpath扫描器中的过滤器进行过滤
				// 如果include过滤器返回的是true && exclude过滤器返回的是false
				//那么就加入candidates并返回
				Set<BeanDefinitionHolder> scannedBeanDefinitions =
						this.componentScanParser.parse
                    			(componentScan, sourceClass.getMetadata().getClassName());

				//扫描的是所有的class 返回的并不是所有的
				//首先beanConfig配置类会被排除,因为注册了一个beanConfig的排除过滤器
				//没有加@Conponent的也会被排除 排除了 TestOrangeCondition 和 Mybean
				//因此剩下了4个
				/**
				 0 =  Aop.class
				 1 = AopLog.class
				 4 = MyPlatformTransactionManager.class
				 6 = TestRegisterResolvableDependency.class
				 */
				//遍历扫描到的BeanDefinitions 判断是否需要解析
				for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
					BeanDefinition bdCand = 
                        holder.getBeanDefinition().getOriginatingBeanDefinition();
					if (bdCand == null) {
						bdCand = holder.getBeanDefinition();
					}
					//判断是否属于候选类
					//判断是否存在@Configuration注解
					//判断是否存在@Bean修饰的方法
                    //判断是否被下面这些注解修饰过
                    //如果是继续被当成配置类解析
					/*
					candidateIndicators.add(Component.class.getName());
					candidateIndicators.add(ComponentScan.class.getName());
					candidateIndicators.add(Import.class.getName());
					candidateIndicators.add(ImportResource.class.getName());
					*/
					if (ConfigurationClassUtils.checkConfigurationClassCandidate
                        					(bdCand, this.metadataReaderFactory)) {
						//解析 解析出来的BeanDefinition
						//这里是一个递归处理 又进入了processConfigurationClass方法
						parse(bdCand.getBeanClassName(), holder.getBeanName());
					}
				}
			}
		}

递归处理@Import

立刻处理ImportSelector

延迟处理DeferredImportSelector

延迟处理ImportBeanDefinitionRegistrar

ImportSelector、DeferredImportSelector、ImportBeanDefinitionRegistrar

public interface ImportSelector {
	String[] selectImports(AnnotationMetadata importingClassMetadata);
}
public interface DeferredImportSelector extends ImportSelector {

	@Nullable
	default Class<? extends Group> getImportGroup() {
		return null;
	}
 
	interface Group {

 
	void process(AnnotationMetadata metadata, DeferredImportSelector selector);
 
		Iterable<Entry> selectImports();

 
		class Entry {

			private final AnnotationMetadata metadata;

			private final String importClassName;

			public Entry(AnnotationMetadata metadata, String importClassName) {
				this.metadata = metadata;
				this.importClassName = importClassName;
			}
 
			public AnnotationMetadata getMetadata() {
				return this.metadata;
			}
 
			public String getImportClassName() {
				return this.importClassName;
			}

			@Override
			public boolean equals(@Nullable Object other) {
				if (this == other) {
					return true;
				}
				if (other == null || getClass() != other.getClass()) {
					return false;
				}
				Entry entry = (Entry) other;
				return (this.metadata.equals(entry.metadata)
                        && this.importClassName.equals(entry.importClassName));
			}

			@Override
			public int hashCode() {
				return (this.metadata.hashCode() * 31 + 
                        		this.importClassName.hashCode());
			}

			@Override
			public String toString() {
				return this.importClassName;
			}
		}
	}
}

@ImportResource导入资源加入集合

将@Bean方法加入集合

递归处理接口@Bean默认方法

延迟处理DeferredImportSelector

deferredImportSelectorHandler.process()

入口:this.deferredImportSelectorHandler.process();
public void process() {
    		//在处理@Import注解时
    		//DeferredImportSelector的实现类已经实例化
    		//并封装为DeferredImportSelectorHolder
    		//放入deferredImportSelectors集合
			List<DeferredImportSelectorHolder> deferredImports
                						= this.deferredImportSelectors;
			this.deferredImportSelectors = null;
			try {
				if (deferredImports != null) {
					DeferredImportSelectorGroupingHandler handler
                        	= new DeferredImportSelectorGroupingHandler();
					deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);
					deferredImports.forEach(handler::register);
                    //进入这里
                    //handler是DeferredImportSelectorHolder
					handler.processGroupImports();
				}
			}
			finally {
				this.deferredImportSelectors = new ArrayList<>();
			}
		}
	}

processGroupImports

	public void processGroupImports() {
			for (DeferredImportSelectorGrouping grouping : 
                 						this.groupings.values()) {
                //调用getImports
				grouping.getImports().forEach(entry -> {
					ConfigurationClass configurationClass = 
                        this.configurationClasses.get(entry.getMetadata());
					try {
                        //调用processImports方法
                        //也就是5.4步的processImports方法
                        //将这些被DeferredSelectImporter接口导入的类
                        //作为普通的@Configuration的Class被解析
						processImports
                         	(configurationClass, 
                          	asSourceClass(configurationClass),
						  	asSourceClasses(entry.getImportClassName()),
                            false);
					}
					catch (BeanDefinitionStoreException ex) {
						throw ex;
					}
					catch (Throwable ex) {
						throw new BeanDefinitionStoreException(
									"Failed to process import candidates 
                            				"for configuration class ", ex);
					}
				});
			}
		}

getImports

public Iterable<Group.Entry> getImports() {
			for (DeferredImportSelectorHolder deferredImport : 
                 							this.deferredImports) {
                //调用process方法
				this.group.process 
                    (deferredImport.getConfigurationClass().getMetadata(),
				    						deferredImport.getImportSelector());
			}
    		//返回的是调用Selector的selectImports
			return this.group.selectImports();
		}

//DefaultDeferredImportSelectorGroup#process
@Override
public void process(AnnotationMetadata metadata,
                    		DeferredImportSelector selector) {		
    		//调用Selector接口的selectImports方法
    		//返回的importClassName是:deferred.AopLog
			for (String importClassName : selector.selectImports(metadata)) {
                //往imports里面添加 1个 Entry
                //Entry里封装了 deferred.AopLog
				this.imports.add(new Entry(metadata, importClassName));
			}
		}

processImports

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection<SourceClass> importCandidates, boolean checkForCircularImports) {

		if (importCandidates.isEmpty()) {
			return;
		}
		//检测Import循环依赖
		if (checkForCircularImports && isChainedImportOnStack(configClass)) {
			this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
		}else {
			this.importStack.push(configClass);
			try {
				//遍历的importCandidates 是@Import导入的类集合
				for (SourceClass candidate : importCandidates) {
					//如果导入的类是实现了ImportSelector接口
					if (candidate.isAssignable(ImportSelector.class)) {
						// 处理 ImportSelector
						Class<?> candidateClass = candidate.loadClass();
						ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
						ParserStrategyUtils.invokeAwareMethods(
								selector, this.environment, this.resourceLoader, this.registry);
						//判断是否是DeferredImportSelector 延迟加载的selector
						if (selector instanceof DeferredImportSelector) {
							this.deferredImportSelectorHandler.handle
                                		(configClass, (DeferredImportSelector) selector);
						}
						//ImportSelector 立即加载的selector
						else {
							//普通的ImportSelector ,执行其selectImports方法,获取需要导入的类的全限定类名数组
							String[] importClassNames
                                = selector.selectImports(currentSourceClass.getMetadata());
							//遍历selectImports方法导入的类名
							Collection<SourceClass> importSourceClasses
                                		= asSourceClasses(importClassNames);
							// 递归调用
							processImports
                                	(configClass, currentSourceClass, importSourceClasses, false);
						}
					}
					//处理实现ImportBeanDefinitionRegistrar接口的类
					else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
						// Candidate class is an ImportBeanDefinitionRegistrar ->
						// delegate to it to register additional bean definitions
						Class<?> candidateClass = candidate.loadClass();
						ImportBeanDefinitionRegistrar registrar =
								BeanUtils.instantiateClass
                            		(candidateClass, ImportBeanDefinitionRegistrar.class);
						ParserStrategyUtils.invokeAwareMethods(
								registrar, this.environment, this.resourceLoader, this.registry);
						configClass.addImportBeanDefinitionRegistrar
                            	(registrar, currentSourceClass.getMetadata());
					}else {
						//@Import导入的类既没有实现ImportSelector接口也没有实现
                        //ImportBeanDefinitionRegistrar接口
						//也就是最后@Import导入的类一定会被当做配置类解析
						// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar 
						// ->process it as an @Configuration class
						// 普通 @Configuration class
						this.importStack.registerImport(
								currentSourceClass.getMetadata(), 
                            			candidate.getMetadata().getClassName());
                        //deferred.AOP被作为配置类导入
						// 递归解析导入的@Configuration class
                        // 递归解析导入的@Configuration class
                        // 递归解析导入的@Configuration class
                        // 递归解析导入的@Configuration class
                        processConfigurationClass(candidate.asConfigClass(configClass));
					}
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to process import candidates for configuration class [" +
						configClass.getMetadata().getClassName() + "]", ex);
			}
			finally {
				this.importStack.pop();
			}
		}
	}
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
		//判断是否需要跳过 比如有@Conditional注解就要跳过
		if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
			return;
		}

		ConfigurationClass existingClass = this.configurationClasses.get(configClass);
		if (existingClass != null) {
			if (configClass.isImported()) {
				if (existingClass.isImported()) {
					existingClass.mergeImportedBy(configClass);
				}
				// Otherwise ignore new imported config class; existing non-imported class overrides it.
				return;
			}
			else {
				// Explicit bean definition found, probably replacing an import.
				// Let's remove the old one and go with the new one.
				this.configurationClasses.remove(configClass);
				this.knownSuperclasses.values().removeIf(configClass::equals);
			}
		}

		// Recursively process the configuration class and its superclass hierarchy.
		SourceClass sourceClass = asSourceClass(configClass);
		do {
			//真正解析的地方
			sourceClass = doProcessConfigurationClass(configClass, sourceClass);
		}
		while (sourceClass != null);

		this.configurationClasses.put(configClass, configClass);
	}

loadBeanDefinitions(configClasses);

处理@Bean方法

处理ImportedResources

处理ImportBeanDefinitionRegistrar

private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {

		if (trackedConditionEvaluator.shouldSkip(configClass)) {
			String beanName = configClass.getBeanName();
			if (StringUtils.hasLength(beanName) && 	
                		this.registry.containsBeanDefinition(beanName)){
				this.registry.removeBeanDefinition(beanName);
			}
			this.importRegistry.removeImportingClass
                		(configClass.getMetadata().getClassName());
			return;
		}

		if (configClass.isImported()) {
			registerBeanDefinitionForImportedConfigurationClass(configClass);
		}
    	//处理@Bean对应的方法
    	//将他们注册到beanDefinitionMap中
    	//其实是注册了一个bean
		for (BeanMethod beanMethod : configClass.getBeanMethods()) {
			loadBeanDefinitionsForBeanMethod(beanMethod);
		}
		//导入ImportedResources
    	//解析文件导入beanDefinition
		loadBeanDefinitionsFromImportedResources
            		(configClass.getImportedResources());
    	//导入Registrars
		loadBeanDefinitionsFromRegistrars
            		(configClass.getImportBeanDefinitionRegistrars());
	}