spring源码解析--上
本文是作者原创,版权归作者所有.若要转载,请注明出处.
首先是配置类
package com.lusai.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.lusai.service")
public class SpringConfig {
}
然后是IndexService
package com.lusai.service; import org.springframework.stereotype.Service; @Service public class IndexService { public void hello(){ System.out.println("IndexService"); } }
然后是测试
public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class);//从这里开始看 IndexService indexService = (IndexService) applicationContext.getBean("indexService"); indexService.hello(); }
看结果
可以看到,IndexService 已经交给spring管理了,我们就开始学习源码吧
/**
* 这个构造方法需要传入一个配置类
* 然后会把这个被注解了的类通过注解读取器读取,继而解析
* Create a new AnnotationConfigApplicationContext, deriving bean definitions
* from the given annotated classes and automatically refreshing the context.
* @param annotatedClasses one or more annotated classes,
* e.g. {@link Configuration @Configuration} classes
*/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//annotatedClasses ---> 配置类的class对象
//这里由于他有父类,故而会先调用父类的构造方法,然后才会调用自己的构造方法
//在自己构造方法中初始一个读取器和扫描器
this();//进这里看
register(annotatedClasses);
refresh();
}
继续看this()
/** * 初始化一个bean的读取器和扫描器 * 何谓读取器和扫描器参考上面的属性注释 * 默认构造函数,如果直接调用这个默认构造方法,需要在稍后通过调用其register() * 去注册配置类(javaconfig),并调用refresh()方法刷新容器, * 触发容器对注解Bean的载入、解析和注册过程 * Create a new AnnotationConfigApplicationContext that needs to be populated * through {@link #register} calls and then manually {@linkplain #refresh refreshed}. */ public AnnotationConfigApplicationContext() { /** * 父类的构造方法 * 创建一个读取注解的Bean定义读取器 * 什么是BeanDefinition */ this.reader = new AnnotatedBeanDefinitionReader(this); //可以用来扫描包或者类,继而转换成BeanDefinition //但是实际上我们扫描包工作不是scanner这个对象来完成的 //是spring自己new的一个ClassPathBeanDefinitionScanner //这里的scanner仅仅是为了程序员能够在外部调用AnnotationConfigApplicationContext对象的scan方法 this.scanner = new ClassPathBeanDefinitionScanner(this); }
我们看一下this.reader
/** * 这个类顾名思义是一个reader,一个读取器 * 读取什么呢?还是顾名思义:AnnotatedBeanDefinition意思是读取一个被加了注解的BeanDefinition * 这个类在构造方法中实例化的 */ private final AnnotatedBeanDefinitionReader reader;
我们再看一下AnnotatedBeanDefinitionReader 的定义
可以看出有个BeanDefinitionRegistry,看这个名字应该是BeanDefinition的注册器,那么BeanDefinition是什么呢,看一下
/** * BeanDefinition描述了一个bean实例 * A BeanDefinition describes a bean instance, which has property values, * constructor argument values, and further information supplied by * concrete implementations. * * <p>This is just a minimal interface: The main intention is to allow a * {@link BeanFactoryPostProcessor} such as {@link PropertyPlaceholderConfigurer} * to introspect and modify property values and other bean metadata. * * @author Juergen Hoeller * @author Rob Harrop * @since 19.03.2004 * @see ConfigurableListableBeanFactory#getBeanDefinition * @see org.springframework.beans.factory.support.RootBeanDefinition * @see org.springframework.beans.factory.support.ChildBeanDefinition */ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { /** * 单例作用域的作用域标识符:“singleton”。 * Scope identifier for the standard singleton scope: "singleton". * <p>Note that extended bean factories might support further scopes. * @see #setScope */ String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; /** * 非单例作用域的作用域标识符:“prototype”。 * Scope identifier for the standard prototype scope: "prototype". * <p>Note that extended bean factories might support further scopes. * @see #setScope */ String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE; /** * 还没搞懂 权限的值 * Role hint indicating that a {@code BeanDefinition} is a major part * of the application. Typically corresponds to a user-defined bean. */ int ROLE_APPLICATION = 0; /** * Role hint indicating that a {@code BeanDefinition} is a supporting * part of some larger configuration, typically an outer * {@link org.springframework.beans.factory.parsing.ComponentDefinition}. * {@code SUPPORT} beans are considered important enough to be aware * of when looking more closely at a particular * {@link org.springframework.beans.factory.parsing.ComponentDefinition}, * but not when looking at the overall configuration of an application. */ int ROLE_SUPPORT = 1; /** * Role hint indicating that a {@code BeanDefinition} is providing an * entirely background role and has no relevance to the end-user. This hint is * used when registering beans that are completely part of the internal workings * of a {@link org.springframework.beans.factory.parsing.ComponentDefinition}. * 就是我这Bean是Spring自己的,和你用户没有一毛钱关系 */ int ROLE_INFRASTRUCTURE = 2; // Modifiable attributes /** * 设置父BeanDefinition的名字 * Set the name of the parent definition of this bean definition, if any. */ void setParentName(@Nullable String parentName); /** * 获得父BeanDefinition的名字 * Return the name of the parent definition of this bean definition, if any. */ @Nullable String getParentName(); /** * 指定此BeanDefinition的bean类名 * Specify the bean class name of this bean definition. * <p>The class name can be modified during bean factory post-processing, * typically replacing the original class name with a parsed variant of it. * @see #setParentName * @see #setFactoryBeanName * @see #setFactoryMethodName */ void setBeanClassName(@Nullable String beanClassName); /** * 获取此BeanDefinition的bean类名 * Return the current bean class name of this bean definition. * <p>Note that this does not have to be the actual class name used at runtime, in * case of a child definition overriding/inheriting the class name from its parent. * Also, this may just be the class that a factory method is called on, or it may * even be empty in case of a factory bean reference that a method is called on. * Hence, do <i>not</i> consider this to be the definitive bean type at runtime but * rather only use it for parsing purposes at the individual bean definition level. * @see #getParentName() * @see #getFactoryBeanName() * @see #getFactoryMethodName() */ @Nullable String getBeanClassName(); /** *设置此BeanDefinition的scope的类型 * Override the target scope of this bean, specifying a new scope name. * @see #SCOPE_SINGLETON * @see #SCOPE_PROTOTYPE */ void setScope(@Nullable String scope); /** * 获取此BeanDefinition的scope的类型 * Return the name of the current target scope for this bean, * or {@code null} if not known yet. */ @Nullable String getScope(); /** * 设置懒加载 * Set whether this bean should be lazily initialized. * <p>If {@code false}, the bean will get instantiated on startup by bean * factories that perform eager initialization of singletons. */ void setLazyInit(boolean lazyInit); /** * 获取是否懒加载 * Return whether this bean should be lazily initialized, i.e. not * eagerly instantiated on startup. Only applicable to a singleton bean. */ boolean isLazyInit(); /** * 设置dependsOn,将首先初始化这些bean * Set the names of the beans that this bean depends on being initialized. * The bean factory will guarantee that these beans get initialized first. */ void setDependsOn(@Nullable String... dependsOn); /** * 获取被dependsOn的beans的名字 * Return the bean names that this bean depends on. */ @Nullable String[] getDependsOn(); /** * 设置是否参与自动装配的候选,与autowire-candidate有关 * Set whether this bean is a candidate for getting autowired into some other bean. * <p>Note that this flag is designed to only affect type-based autowiring. * It does not affect explicit references by name, which will get resolved even * if the specified bean is not marked as an autowire candidate. As a consequence, * autowiring by name will nevertheless inject a bean if the name matches. */ void setAutowireCandidate(boolean autowireCandidate); /** * 获取是否参与自动装配的候选 * Return whether this bean is a candidate for getting autowired into some other bean. */ boolean isAutowireCandidate(); /** * 设置@Primay注解 * Set whether this bean is a primary autowire candidate. * <p>If this value is {@code true} for exactly one bean among multiple * matching candidates, it will serve as a tie-breaker. */ void setPrimary(boolean primary); /** * 获取该bean是否被@Primay注解 * Return whether this bean is a primary autowire candidate. */ boolean isPrimary(); /** * Specify the factory bean to use, if any. * This the name of the bean to call the specified factory method on. * @see #setFactoryMethodName */ void setFactoryBeanName(@Nullable String factoryBeanName); /** * Return the factory bean name, if any. */ @Nullable String getFactoryBeanName(); /** * 与bean标签的factory-method有关 * Specify a factory method, if any. This method will be invoked with * constructor arguments, or with no arguments if none are specified. * The method will be invoked on the specified factory bean, if any, * or otherwise as a static method on the local bean class. * @see #setFactoryBeanName * @see #setBeanClassName */ void setFactoryMethodName(@Nullable String factoryMethodName); /** * Return a factory method, if any. */ @Nullable String getFactoryMethodName(); /** * 存放构造方法的参数和顺序等 constructor-arg标签的index和name等属性 * Return the constructor argument values for this bean. * <p>The returned instance can be modified during bean factory post-processing. * @return the ConstructorArgumentValues object (never {@code null}) */ ConstructorArgumentValues getConstructorArgumentValues(); /** * 判断构造方法有没有参数值 * Return if there are constructor argument values defined for this bean. * @since 5.0.2 */ default boolean hasConstructorArgumentValues() { return !getConstructorArgumentValues().isEmpty(); } /** * bean标签的property属性 * Return the property values to be applied to a new instance of the bean. * <p>The returned instance can be modified during bean factory post-processing. * @return the MutablePropertyValues object (never {@code null}) */ MutablePropertyValues getPropertyValues(); /** * Return if there are property values values defined for this bean. * @since 5.0.2 */ default boolean hasPropertyValues() { return !getPropertyValues().isEmpty(); } /** * Set the name of the initializer method. * @since 5.1 */ void setInitMethodName(@Nullable String initMethodName); /** * Return the name of the initializer method. * @since 5.1 */ @Nullable String getInitMethodName(); /** * Set the name of the destroy method. * @since 5.1 */ void setDestroyMethodName(@Nullable String destroyMethodName); /** * Return the name of the destroy method. * @since 5.1 */ @Nullable String getDestroyMethodName(); /** * Set the role hint for this {@code BeanDefinition}. The role hint * provides the frameworks as well as tools with an indication of * the role and importance of a particular {@code BeanDefinition}. * @since 5.1 * @see #ROLE_APPLICATION * @see #ROLE_SUPPORT * @see #ROLE_INFRASTRUCTURE */ void setRole(int role); /** * Get the role hint for this {@code BeanDefinition}. The role hint * provides the frameworks as well as tools with an indication of * the role and importance of a particular {@code BeanDefinition}. * @see #ROLE_APPLICATION * @see #ROLE_SUPPORT * @see #ROLE_INFRASTRUCTURE */ int getRole(); /** * @Description注解,描述,无太大意义 * Set a human-readable description of this bean definition. * @since 5.1 */ void setDescription(@Nullable String description); /** * Return a human-readable description of this bean definition. */ @Nullable String getDescription(); // Read-only attributes /** * Return whether this a <b>Singleton</b>, with a single, shared instance * returned on all calls. * @see #SCOPE_SINGLETON */ boolean isSingleton(); /** * Return whether this a <b>Prototype</b>, with an independent instance * returned for each call. * @since 3.0 * @see #SCOPE_PROTOTYPE */ boolean isPrototype(); /** * 判断是否是抽象类,为什么可以是抽象类 * Return whether this bean is "abstract", that is, not meant to be instantiated. */ boolean isAbstract(); /** * 对文件的描述 * Return a description of the resource that this bean definition * came from (for the purpose of showing context in case of errors). */ @Nullable String getResourceDescription(); /** * Return the originating BeanDefinition, or {@code null} if none. * Allows for retrieving the decorated bean definition, if any. * <p>Note that this method returns the immediate originator. Iterate through the * originator chain to find the original BeanDefinition as defined by the user. */ @Nullable BeanDefinition getOriginatingBeanDefinition(); }
BeanDefinition描述了一个bean实例,可以理解为:我们定义的对象交给spring管理以后会变成一个个BeanDefinition
好了,看看下一个
//可以用来扫描包或者类,继而转换成BeanDefinition //但是实际上我们扫描包工作不是scanner这个对象来完成的 //是spring自己new的一个ClassPathBeanDefinitionScanner //这里的scanner仅仅是为了程序员能够在外部调用AnnotationConfigApplicationContext对象的scan方法 this.scanner = new ClassPathBeanDefinitionScanner(this);
这里的scanner 我们也不深究,姑且认为是一个扫描器
继续看构造方法
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { //annotatedClasses ---> 配置类的class对象 //这里由于他有父类,故而会先调用父类的构造方法,然后才会调用自己的构造方法 //在自己构造方法中初始一个读取器和扫描器 this(); register(annotatedClasses);//进这里看 refresh(); }
看register方法
/** * 注册单个bean给容器 * 比如有新加的类可以用这个方法 * 但是注册注册之后需要手动调用refresh方法去触发容器解析注解 * * 有两个意思 * 他可以注册一个配置类 * 他还可以单独注册一个bean * Register one or more annotated classes to be processed. * <p>Note that {@link #refresh()} must be called in order for the context * to fully process the new classes. * @param annotatedClasses one or more annotated classes, * e.g. {@link Configuration @Configuration} classes * @see #scan(String...) * @see #refresh() */ public void register(Class<?>... annotatedClasses) { Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified"); this.reader.register(annotatedClasses);//被注解的类 }
我们把配置类的扫描注释掉看下
@Configuration //@ComponentScan("com.lusai.service") public class SpringConfig { }
运行测试类,看下结果
扫描不到报错,我们改成如下形式再试一下
public static void main(String[] args) { //AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class); AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(IndexService.class); IndexService indexService = (IndexService) applicationContext.getBean("indexService"); indexService.hello(); }
看结果
ok,可以看出register方法有两个意思:1.他可以注册一个配置类2.他还可以单独注册一个bean
好了,继续点进去看源码
/** * Register one or more annotated classes to be processed. * <p>Calls to {@code register} are idempotent; adding the same * annotated class more than once has no additional effect. * @param annotatedClasses one or more annotated classes, * e.g. {@link Configuration @Configuration} classes */ public void register(Class<?>... annotatedClasses) { for (Class<?> annotatedClass : annotatedClasses) { registerBean(annotatedClass); } }
继续看registerBean
/** * Register a bean from the given bean class, deriving its metadata from * class-declared annotations. * @param annotatedClass the class of the bean */ public void registerBean(Class<?> annotatedClass) { doRegisterBean(annotatedClass, null, null, null); }
继续看doRegisterBean
/** * Register a bean from the given bean class, deriving its metadata from * class-declared annotations. * @param annotatedClass the class of the bean * @param instanceSupplier a callback for creating an instance of the bean * (may be {@code null}) * @param name an explicit name for the bean * @param qualifiers specific qualifier annotations to consider, if any, * in addition to qualifiers at the bean class level * @param definitionCustomizers one or more callbacks for customizing the * factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag * @since 5.0 */ <T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) { /** * 根据指定的bean创建一个AnnotatedGenericBeanDefinition * 这个AnnotatedGenericBeanDefinition可以理解为一个数据结构 * AnnotatedGenericBeanDefinition包含了类的其他信息,比如一些元信息 * scope,lazy等等. * 此时因为传入的注解,所以new AnnotatedGenericBeanDefinition */ AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass); /** * 判断这个类是否需要跳过解析 * 通过代码可以知道spring判断是否跳过解析,主要判断类有没有加注解 */ if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { return; } abd.setInstanceSupplier(instanceSupplier); /** * 得到类的作用域 singleton */ ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); /** * 把类的作用域添加到数据结构结构中 */ abd.setScope(scopeMetadata.getScopeName()); /** * 生成类的名字通过beanNameGenerator */ String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); /** * 处理类当中的通用注解 * 分析源码可以知道他主要处理 * Lazy DependsOn Primary Role等等注解 * 处理完成之后processCommonDefinitionAnnotations中依然是把他添加到数据结构当中 */ AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); if (qualifiers != null) {//qualifiers总是为null for (Class<? extends Annotation> qualifier : qualifiers) { //如果配置了@Primary注解,如果加了则作为首选 if (Primary.class == qualifier) { abd.setPrimary(true); } //懒加载,前面加过 else if (Lazy.class == qualifier) { abd.setLazyInit(true); } else { //如果使用了除@Primary和@Lazy以外的其他注解,则为该Bean添加一个根据名字自动装配的限定符 //这里难以理解,后面会详细介绍 abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } } //自定义注解 for (BeanDefinitionCustomizer customizer : definitionCustomizers) { customizer.customize(abd); } /** * 这个BeanDefinitionHolder也是一个数据结构,这个对象放入了BeanDefinition和beanName,可以理解为一个map */ BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); /** * ScopedProxyMode 这个知识点比较复杂,需要结合web去理解 * 可以暂时放一下,等说道springmvc的时候再说 * 或者看情况现在说也是一样的 */ definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); /** * 把上述的这个数据结构注册给registry * registy就是AnnotatonConfigApplicationContext * AnnotatonConfigApplicationContext在初始化的時候通過調用父類的構造方法 * 實例化了一个DefaultListableBeanFactory * *registerBeanDefinition里面就是把definitionHolder这个数据结构包含的信息注册到 * DefaultListableBeanFactory这个工厂 */ BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); }
看下这行的源码
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
继续
public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) { processCommonDefinitionAnnotations(abd, abd.getMetadata()); }
继续
/** * 检查常用的注解 * @param abd * @param metadata */ static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) { //检查Lazy注解,如果有将它放入AnnotatedBeanDefinition AnnotationAttributes lazy = attributesFor(metadata, Lazy.class); if (lazy != null) { abd.setLazyInit(lazy.getBoolean("value")); } else if (abd.getMetadata() != metadata) { lazy = attributesFor(abd.getMetadata(), Lazy.class); if (lazy != null) { abd.setLazyInit(lazy.getBoolean("value")); } } //检查Primary注解,如果有将它放入AnnotatedBeanDefinition if (metadata.isAnnotated(Primary.class.getName())) { abd.setPrimary(true); } //检查DependsOn注解,如果有将它放入AnnotatedBeanDefinition AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class); if (dependsOn != null) { abd.setDependsOn(dependsOn.getStringArray("value")); } //检查Role注解,如果有将它放入AnnotatedBeanDefinition AnnotationAttributes role = attributesFor(metadata, Role.class); if (role != null) { abd.setRole(role.getNumber("value").intValue()); } //检查Description注解,如果有将它放入AnnotatedBeanDefinition AnnotationAttributes description = attributesFor(metadata, Description.class); if (description != null) { abd.setDescription(description.getString("value")); } }
分析源码可以知道他主要处理Lazy DependsOn Primary Role等等注解
处理完成之后是把他添加到AnnotatedGenericBeanDefinition数据结构当中
继续看下面
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
看下BeanDefinitionHolder 的定义
这个BeanDefinitionHolder也是一个对象,这个对象放入了BeanDefinition和beanName
好了,我们看最后一行关键代码:
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
点进去
public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // Register bean definition under primary name. String beanName = definitionHolder.getBeanName();//获取beanName registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());//关键代码 //别名,先不看 // Register aliases for bean name, if any. String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String alias : aliases) { registry.registerAlias(beanName, alias); } } }
看那行关键代码
@Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { //DefaultListableBeanFactory this.beanFactory.registerBeanDefinition(beanName, beanDefinition); }
这里的this.beanFactory是DefaultListableBeanFactory,这个是默认的bean工厂
再点进去看
@Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) {//验证 try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } else if (existingDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (logger.isInfoEnabled()) { logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(existingDefinition)) { if (logger.isDebugEnabled()) { logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else { if (logger.isTraceEnabled()) { logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; removeManualSingletonName(beanName); } } else {//关键代码 // Still in startup registration phase //这里的beanDefinitionMap是一个map,存放beanName,beanDefinition this.beanDefinitionMap.put(beanName, beanDefinition); //这里的beanDefinitionNames是一个list,存放beanName this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
看我注释的地方,那里就是关键代码
这里的this.beanDefinitionMap看一下
/** Map of bean definition objects, keyed by bean name. */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
这里我们debug一下
可以看到除了indexService之外很多内置的bean,那么这些类是什么时候注册的,都有什么用呢?我们后面再研究
我们register看完了,现在看refresh方法
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { //annotatedClasses ---> 配置类的class对象 //这里由于他有父类,故而会先调用父类的构造方法,然后才会调用自己的构造方法 //在自己构造方法中初始一个读取器和扫描器 this(); register(annotatedClasses); refresh();//进这里看 }
点进去
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. ////准备工作包括设置启动时间,是否激活标识位, // 初始化属性源(property source)配置 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. //返回一个factory 为什么需要返回一个工厂 //因为要对工厂进行初始化 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. //准备工厂 prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. //这个方法在当前版本的spring是没用任何代码的 //可能spring期待在后面的版本中去扩展吧 postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. //在spring的环境中去执行已经被注册的 factory processors //设置执行自定义的ProcessBeanFactory 和spring内部自己定义的 invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. //注册beanPostProcessor registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. //初始化应用事件广播器 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
看看下面这行
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
点进去
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); return getBeanFactory(); }
继续看getBeanFactory()方法
@Override public final ConfigurableListableBeanFactory getBeanFactory() { return this.beanFactory; }
这里的this.beanFactory就是上文提到的DefaultListableBeanFactory
private final DefaultListableBeanFactory beanFactory;
好,下面我们看这行
prepareBeanFactory(beanFactory);
点进去
/**
*
* 配置其标准的特征,比如上下文的加载器ClassLoader和post-processors回调
* Configure the factory's standard context characteristics,
* such as the context's ClassLoader and post-processors.
* @param beanFactory the BeanFactory to configure
* 此处的beanFactory参数等于DefaultListableFactory
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
//bean表达式解释器,后面说 能够获取bean当中的属性在前台页面
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//对象与string类型的转换 <property red="dao">
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
//添加一个后置管理器
//ApplicationContextAwareProcessor
// 能够在bean中获得到各种*Aware(*Aware都有其作用)
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));//核心代码
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
//意思是如果自定义的Bean中没有名为"systemProperties"和"systemEnvironment"的Bean,
// 则注册两个Bena,Key为"systemProperties"和"systemEnvironment",Value为Map,
// 这两个Bean就是一些系统配置和系统环境信息
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
我们看一下核心的那行代码
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));//核心代码
打断点
@Override public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) { Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null"); // Remove from old position, if any this.beanPostProcessors.remove(beanPostProcessor); // Track whether it is instantiation/destruction aware if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { this.hasInstantiationAwareBeanPostProcessors = true; } if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) { this.hasDestructionAwareBeanPostProcessors = true; } // Add to end of list this.beanPostProcessors.add(beanPostProcessor);//核心代码 }
我们看一下this.beanPostProcessors是什么
/** BeanPostProcessors to apply in createBean. */ private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
BeanPostProcessor就是传说中的后置处理器,通过实现BeanPostProcessor接口,程序员就可插手bean实例化的过程
我们试一下
@Service public class IndexService { public IndexService(){ System.out.println("IndexService 构造方法"); } @PostConstruct public void init(){ System.out.println("IndexService init方法"); } public void hello(){ System.out.println("IndexService"); } }
配置类
@Configuration @ComponentScan("com.lusai") public class SpringConfig { }
实现BeanPostProcessor接口的类
@Component public class TestBeanPostProcessor implements BeanPostProcessor { /** * 在bean初始化之前执行 */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("indexService")){ System.out.println("indexService postProcessBeforeInitialization"); } //这里也可以产生代理对象 Proxy.newProxyInstance() return bean; } /** * 初始化之后 */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("indexService")){ System.out.println("indexService postProcessAfterInitialization"); } return bean; } }
测试类
public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfig.class); //AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(IndexService.class); IndexService indexService = (IndexService) applicationContext.getBean("indexService"); indexService.hello(); }
看下结果
插手成功
好了,我们继续这行代码
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));//核心代码
我们看下此处的ApplicationContextAwareProcessor,这个类实现了BeanPostProcessor 接口,重写了postProcessBeforeInitialization方法
class ApplicationContextAwareProcessor implements BeanPostProcessor { @Override @Nullable public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException { AccessControlContext acc = null; if (System.getSecurityManager() != null && (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) { acc = this.applicationContext.getBeanFactory().getAccessControlContext(); } if (acc != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareInterfaces(bean); return null; }, acc); } else { invokeAwareInterfaces(bean);//看这行 } return bean; }
}
看下那行代码
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {//EnvironmentAware用于获取配置文件
//比如this.applicationContext.getEnvironment().getProperty("url")
//ConfigurableEnvironment environment = this.applicationContext.getEnvironment();
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {//实现ApplicationContextAware接口,可以在spring管理的单例bean中中使用原型依赖bean
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
我们测试一下ApplicationContextAware接口
@Service public class IndexService implements ApplicationContextAware { private ApplicationContext applicationContext; public IndexService(){ System.out.println("IndexService 构造方法"); } @PostConstruct public void init(){ System.out.println("IndexService init方法"); } public void hello(){ System.out.println("IndexService"); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext=applicationContext; System.out.println(applicationContext); } }
运行测试类,看下结果
好了,我们继续看源码
//目前是空方法,留给后续扩展 postProcessBeanFactory(beanFactory); //完成扫描和解析(类--->beanDefinition) beanDefinitionMap // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory);
第一个是空方法,看第二行
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//先看下getBeanFactoryPostProcessors方法
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
先看下getBeanFactoryPostProcessors方法
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() { return this.beanFactoryPostProcessors; }
这里的this.beanFactoryPostProcessors就是BeanFactoryPostProcessor的集合,如下
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
那么BeanFactoryPostProcessor是什么?有什么用呢?
BeanFactoryPostProcessor是spring的扩展点之一 * 实现该接口,可以在spring的bean创建之前修改bean的定义属性。 * spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据, * 并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。 * 可以同时配置多个BeanFactoryPostProcessor,并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序。 * BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后,在bean实例化之前执行的
来测试一下这个功能
@Component public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { BeanDefinition indexService = beanFactory.getBeanDefinition("indexService"); String scope = indexService.getScope(); System.out.println(scope); indexService.setScope("prototype"); System.out.println(scope); } }
这篇就先到这里吧