最简单的启动spring的代码以下:java
import com.ld.test.config.AppConfig; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class TestDemo { public static void main(String[] args) { AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(AppConfig.class); acac.close(); } }
先来看一下AnnotationConfigApplicationContext类的UML图,留个印象。程序员
点开AnnotationConfigApplicationContext(AppConfig.class);方法查看源码:spring
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { // 调用默认无参构造器,里面有一大堆初始化逻辑 // 开天辟地初始化两个类 // AnnotatedBeanDefinitionReader reader; // ClassPathBeanDefinitionScanner scanner; this(); // 把传入的Class进行注册,Class既能够有@Configuration注解,也能够没有@Configuration注解 // // 有@Configuration // map.put("org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass","full") // 没有有@Configuration // map.put("org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass","lite") // // 怎么注册? 委托给了 org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register 方法进行注册 // 传入Class 生成 BeanDefinition , 而后经过 注册到 BeanDefinitionRegistry register(annotatedClasses); // 刷新容器上下文 refresh(); }
该构造器容许咱们传入一个或者多个class对象。class对象能够是被@Configuration标注的,也能够是一个普通的Java 类。app
有参构造器调用了无参构造器,点开源码:ide
public AnnotationConfigApplicationContext() { // 隐式调用父类构造器,初始化beanFactory,具体实现类为DefaultListableBeanFactory // super(); // 建立 AnnotatedBeanDefinitionReader, // 建立时会向传入的 BeanDefinitionRegistry 中 注册 注解配置相关的 processors 的 BeanDefinition this.reader = new AnnotatedBeanDefinitionReader(this); // 经过后面的源码探究也能够发现,spring并非使用这个scanner来扫描包获取Bean的 this.scanner = new ClassPathBeanDefinitionScanner(this); }
初始化子类时会先初始化父类,会默认调用父类无参构造器。AnnotationConfigApplicationContext继承了GenericApplicationContext,在GenericApplicationContext的无参构造器中,建立了BeanFactory的具体实现类DefaultListableBeanFactory。spring中的BeanFactory就是在这里被实例化的,而且使用DefaultListableBeanFactory作的BeanFactory的默认实现。函数
public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); }
AnnotationConfigApplicationContext的构造器中还建立了两个对象:AnnotatedBeanDefinitionReader 和 ClassPathBeanDefinitionScanner。post
先说scanner的做用,经过查看源码能够发现,这个scanner只有在手动调用AnnotationConfigApplicationContext的一些方法的时候才会被使用(经过后面的源码探究也能够发现,spring并非使用这个scanner来扫描包获取Bean的)ui
建立AnnotatedBeanDefinitionReader对象。spring在建立reader的时候把this当作了参数传给了构造器。也就是说,reader对象里面包含了一个this对象,也就是AnnotationConfigApplicationContext对象。AnnotationConfigApplicationContext 实现了BeanDefinitionRegistry接口。点开this.reader = new AnnotatedBeanDefinitionReader(this);源码:this
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, getOrCreateEnvironment(registry)); }
从传入的BeanDefinitionRegistry对象,也就是AnnotationConfigApplicationContext对象中获取Environment(共用同一个Environment),而后又接着调用另外一个构造器。点开源码:lua
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); this.registry = registry; this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); //在 BeanDefinitionRegistry 中注册 注解配置相关的 processors AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }
在这个构造器中,执行了一个很是重要的方法AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); 顾名思义,spring经过这个方法注册了解析注解配置相关的处理器。点开源码:
第一步:设置属性
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) { DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { // AnnotationAwareOrderComparator是OrderComparator的子类,用来支持Spring的Ordered类、@Order注解和@Priority注解。 beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { // 设置依赖注入的候选处理器 // 能够看到只要不是ContextAnnotationAutowireCandidateResolver类型 直接升级为最强类型 beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } // 代码省略。。。 }
注册的是一些spring内置的PostProcessor的BeanDefinition
2.一、 ConfigurationClassPostProcessor
ConfigurationClassPostProcessor是一个BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor处理器,BeanDefinitionRegistryPostProcessor的处理方法能处理@Configuration等注解。ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry()方法内部处理@Configuration,@Import,@ImportResource和类内部的@Bean。
ConfigurationClassPostProcessor类继承了BeanDefinitionRegistryPostProcessor。BeanDefinitionRegistryPostProcessor类继承了BeanFactoryPostProcessor。经过BeanDefinitionRegistryPostProcessor能够建立一个特别后置处理器来将BeanDefinition添加到BeanDefinitionRegistry中。它和BeanPostProcessor不一样,BeanPostProcessor只是在Bean初始化的时候有个钩子让咱们加入一些自定义操做;而BeanDefinitionRegistryPostProcessor可让咱们在BeanDefinition中添加一些自定义操做。在Mybatis与Spring的整合中,就利用到了BeanDefinitionRegistryPostProcessor来对Mapper的BeanDefinition进行了后置的自定义处理。
2.二、AutowiredAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor是用来处理@Autowired注解和@Value注解的
2.三、RequiredAnnotationBeanPostProcessor
RequiredAnnotationBeanPostProcessor这是用来处理@Required注解
2.四、CommonAnnotationBeanPostProcessor
提供对JSR-250规范注解的支持@javax.annotation.Resource、@javax.annotation.PostConstruct和@javax.annotation.PreDestroy等的支持。
2.五、EventListenerMethodProcessor
EventListenerMethodProcessor提供@PersistenceContext的支持。
EventListenerMethodProcessor提供@ EventListener 的支持。@ EventListener实在spring4.2以后出现的,能够在一个Bean的方法上使用@EventListener注解来自动注册一个ApplicationListener。
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) { // 代码省略。。。。 Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8); // 第一个问题 了解 RootBeanDefinition - > AbstractBeanDefinition // 第二个问题 了解 registerPostProcessor(); if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { //org.springframework.context.annotation.internalConfigurationAnnotationProcessor - ConfigurationClassPostProcessor.class //这个类很是的重要,它是一个 BeanDefinitionRegistryPostProcessor RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 代码省略。。。。 逻辑差很少 return beanDefs; }
咱们发现:内部定义的class都是带internal的
一、该方法从传入的BeanDefinitionRegistry对象,也就是AnnotationConfigApplicationContext对象中获取到DefaultListableBeanFactory对象。
二、为获取的DefaultListableBeanFactory对象设置属性
三、往DefaultListableBeanFactory对象中注册BeanDefinition,注册的是一些spring内置的PostProcessor的BeanDefinition(关于BeanDefinition的介绍下期在讲)。注意,此时只是注册BeanDefinition,并无实例化bean。默认状况下,执行完该方法后,spring容器中所注册的BeanDefinition为:
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
ROLE_INFRASTRUCTURE = 2 就是我这Bean是Spring本身的,和你用户没有一毛钱关系
private static BeanDefinitionHolder registerPostProcessor( BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) { definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(beanName, definition); return new BeanDefinitionHolder(definition, beanName); }
所谓的注册BeanDefinition,简单理解就是将BeanDefinition放到DefaultListableBeanFactory.registerBeanDefinition对象的beanDefinitionMap中
@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); //第一次进来existingDefinition确定为null if (existingDefinition != null) { // 代码省略。。。 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 this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
到此为止:DefaultListableBeanFactory.beanDefinitionMap 只有默认的spring beanDefinition
====下面是你们熟悉的注册默认6大后置处理器:====
public AnnotationConfigApplicationContext() { /** * 建立一个读取注解的Bean定义读取器 * 什么是bean定义?BeanDefinition * * 完成了spring内部BeanDefinition的注册(主要是后置处理器) */ this.reader = new AnnotatedBeanDefinitionReader(this); /** * 建立BeanDefinition扫描器 * 能够用来扫描包或者类,继而转换为bd * * spring默认的扫描包不是这个scanner对象 * 而是本身new的一个ClassPathBeanDefinitionScanner * spring在执行工程后置处理器ConfigurationClassPostProcessor时,去扫描包时会new一个ClassPathBeanDefinitionScanner * * 这里的scanner仅仅是为了程序员能够手动调用AnnotationConfigApplicationContext对象的scan方法 * */ this.scanner = new ClassPathBeanDefinitionScanner(this); }
下一步
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, @Nullable ResourceLoader resourceLoader) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry; // 这个确定成功 if (useDefaultFilters) { /** * 注册spring扫描类过滤器 * 加了特定注解的类会被扫描到 * 带有@Component、@Repository、@Service、@Controller、@ManagedBean、@Named */ registerDefaultFilters(); } setEnvironment(environment); setResourceLoader(resourceLoader); }
只关心最后一个构造函数的registerDefaultFilters();方法
/** * 注册过滤器 * 带有@Component、@Repository、@Service、@Controller、@ManagedBean、@Named * 注解的类会被spring扫描到 * * Register the default filter for {@link Component @Component}. * <p>This will implicitly register all annotations that have the * {@link Component @Component} meta-annotation including the * {@link Repository @Repository}, {@link Service @Service}, and * {@link Controller @Controller} stereotype annotations. * <p>Also supports Java EE 6's {@link javax.annotation.ManagedBean} and * JSR-330's {@link javax.inject.Named} annotations, if available. * */ @SuppressWarnings("unchecked") protected void registerDefaultFilters() { this.includeFilters.add(new AnnotationTypeFilter(Component.class)); ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { this.includeFilters.add(new AnnotationTypeFilter( ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false)); logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning"); } catch (ClassNotFoundException ex) { // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip. } try { this.includeFilters.add(new AnnotationTypeFilter( ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false)); logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning"); } catch (ClassNotFoundException ex) { // JSR-330 API not available - simply skip. } }
扫描过滤器includeFilters与excludeFilters
首先这里的includeFilters你们熟悉吗,还有个excludeFilters,先看一下属性
private final List<TypeFilter> includeFilters = new LinkedList<>(); private final List<TypeFilter> excludeFilters = new LinkedList<>();
这里提早往includeFilters里面添加须要扫描的特定注解
1.添加元注解@Component,须要注意的是@Repository、@Service、@Controller里面都标注了@Component。很好理解,扫描的时候用includeFilters 去过滤时,会找到并处理这4个注解的类。
2.下面两个注解@ManagedBean、@Named须要有对应的jar包,不然(也就是说把这个方法走完),includeFilters里面只会有一个元素
this.reader = new AnnotatedBeanDefinitionReader(this); 完成了spring内部BeanDefinition的注册(主要是后置处理器)
一、beanDefinitionMap存放了全部的Defintion 以 key-value
二、List<String> beanDefinitionNames 存放了全部的beanDefintion名字
this.scanner = new ClassPathBeanDefinitionScanner(this);
一、这里的scanner仅仅是为了程序员能够手动调用AnnotationConfigApplicationContext对象的scan方法
二、提供了includeFilters 和 excludeFilters 这里是一个扩展点
到此开天辟地初始化两句代码就完成了他们的使命。
一、ContextAnnotationAutowireCandidateResolver 后面解释?
二、RootBeanDefinition -> AbstractBeanDefinition->BeanDefinition 后面解释?
三、各类Processor解释?
四、如何扩展includeFilters 和 excludeFilters 这里是一个扩展点?