Spring的入门代码:
public class XmlTest {public static void main(String[] args) {//构造一个容器.ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("springTest.xml");//从容器中获取Bean对象UserService userService = (UserService) context.getBean("userService");UserService a1 = (UserService) context.getBean("a1");UserService a2 = (UserService) context.getBean("a2");UserService a3 = (UserService) context.getBean("a3");//调用方法userService.test();a1.test();a2.test();a3.test();}
}
public class UserService {public void test() {System.out.println("我是一个bean");}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"
><bean id="a1" class="com.itbo.service.UserService"/><bean id="a2" class="com.itbo.service.UserService"/><bean id="a3" class="com.itbo.service.UserService"/><bean id="userService" class="com.itbo.service.UserService" autowire="default"></bean>
</beans>
以上就是入门的Spring代码.
1:第一行代码,会构造一个ClassPathXmlApplicationContext对象,ClassPathXmlApplicationContext该如何理解,调用该构造方法除开会实例化得到一个对象
2: 会调用ClassPathXmlApplicationContext的getBean方法,会得到一个UserService对象,getBean()是如何实现的?返回的UserService对象和我们自己直接new的UserService对象有区别吗?
3:就是简单的调用UserService的test()方法.
但是用ClassPathXmlApplicationContext其实已经过时了,在新版的Spring MVC和Spring Boot的底层主要用的都是AnnotationConfigApplicationContext,比如:
public class AnnotationTest {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserService userService = (UserService) context.getBean("userService");userService.test();}
}
@ComponentScan("com.itbo")
public class AppConfig {@Beanpublic UserService userService() {return new UserService();}
}
目前,我们基本很少直接使用上面这种方式来用Spring,而是使用Spring MVC,或者Spring Boot,但是它们都是基于上面这种方式的,都需要在内部去创建一个ApplicationContext的,只不过:
- Spring MVC创建的是XmlWebApplicationContext,和ClassPathXmlApplicationContext类似,都是基于XML配置的
- Spring Boot创建的是AnnotationConfigApplicationContext.
因为AnnotationConfigApplicationContext是比较重要的,并且AnnotationConfigApplicationContext和ClassPathXmlApplicationContext大部分底层都是共同的.所以我们就分析AnnotationConfigApplicationContext的流程.
执行流程
然后进入到构造方法里面会看到如下图.
那我们就挨个点着进去大概看一下.this方法如下.
看着注释,很蒙圈,怎么就注册了那么多BeanPostProcessor,那就无脑点进去看看满足自己的好奇心.
都到这里了,心里还能控制住嘛.不得继续进去看看,有个啥东西嘛.
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);if (beanFactory != null) {// 设置beanFactory的OrderComparator,为AnnotationAwareOrderComparator// 它是一个Comparator,是一个比较器,可以用来进行排序,比如new ArrayList<>().sort(Comparator)if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);}// 设置自动装配候选者解析式(判断某个bean是不是可以用来进行进行自动注入),用来解析某个bean能不能进行自动注入,bean的autowireCandidate的属性是否为true.if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());}}Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);// 注册ConfigurationClassPostProcessor类型的BeanDefinitionif (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}// 注册AutowiredAnnotationBeanPostProcessor类型的BeanDefinitionif (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}// 注册CommonAnnotationBeanPostProcessor类型的BeanDefinition// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));}// 注册PersistenceAnnotationBeanPostProcessor类型的BeanDefinition// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.//@PersistenceUnit和@PersistenceContext注解的注入点的查找.类似于autowired和resource.if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition();try {def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,AnnotationConfigUtils.class.getClassLoader()));}catch (ClassNotFoundException ex) {throw new IllegalStateException("Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);}def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));}// 注册EventListenerMethodProcessor类型的BeanDefinitionif (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));}// 注册DefaultEventListenerFactory类型的BeanDefinitionif (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));}return beanDefs;}
这里是注册了一些最基本的PostProcesser,切记切记,一定要有个印象.(可以手动注册,也可以利用配置bean的方式,不懂,先记住.方便后面理解)
回过头来继续点进去注册过滤的那个类.
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,Environment environment, @Nullable ResourceLoader resourceLoader) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");this.registry = registry;// 添加includeFilters,Spring扫描的时候需要利用includeFilters,Spring扫描到某个类时如果能通过includeFilters的验证就证明这个类是一个Bean// 默认注册一个@Component注解对应的Filterif (useDefaultFilters) {registerDefaultFilters();}setEnvironment(environment);setResourceLoader(resourceLoader);}
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.}}
内部的实现就是这样的.可能初看不懂,没关系,记住,有个大概印象.源码就是反复看重复看的.
this方法看完了,退回到构造方法,继续看注册配置类的方法.
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,@Nullable BeanDefinitionCustomizer[] customizers) {// 直接生成一个AnnotatedGenericBeanDefinitionAnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);// 判断当前abd是否被标注了@Conditional注解,并判断是否符合所指定的条件,如果不符合,则跳过,不进行注册if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}// 设置supplier、scope属性,以及得到beanNameabd.setInstanceSupplier(supplier);// @Scope注解的元数据信息ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);abd.setScope(scopeMetadata.getScopeName());String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));// 获取Lazy、Primary、DependsOn、Role、Description注解信息并设置给abdAnnotationConfigUtils.processCommonDefinitionAnnotations(abd);if (qualifiers != null) {for (Class<? extends Annotation> qualifier : qualifiers) {if (Primary.class == qualifier) {abd.setPrimary(true);}else if (Lazy.class == qualifier) {abd.setLazyInit(true);}else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));}}}// 使用自定义器修改BeanDefinitionif (customizers != null) {for (BeanDefinitionCustomizer customizer : customizers) {customizer.customize(abd);}}// BeanDefinition中是没有beanName的,BeanDefinitionHolder中持有了BeanDefinition,beanName,aliasBeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);// 解析Scope中的ProxyMode属性,默认为no,不生成代理对象definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);// 注册到registry中BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);}
思路就是封装成一个BeanDefinition然后注册到BeanFactory中.
在回到构造方法进入到refresh方法中.
@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();// Tell the subclass to refresh the internal bean factory.// 刷新BeanFactory,得到一个空的BeanFactory-DefaultConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // co// Prepare the bean factory for use in this context.// 准备BeanFactory// 1. 设置BeanFactory的类加载器、表达式解析器、类型转化注册器// 2. 添加三个BeanPostProcessor,注意是具体的BeanPostProcessor实例对象// 3. 记录ignoreDependencyInterface// 4. 记录ResolvableDependency// 5. 添加三个单例BeanprepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.// 子类可以对BeanFactory进行进一步初始化postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.// BeanFactory准备好了之后,执行BeanFactoryPostProcessor,开始对BeanFactory进行处理// 默认情况下:// 此时beanFactory的beanDefinitionMap中有6个BeanDefinition,5个基础BeanDefinition+AppConfig的BeanDefinition// 而这6个中只有一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor// 这里会执行ConfigurationClassPostProcessor进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中// 注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行invokeBeanFactoryPostProcessors(beanFactory); //BeanDefinitionRegistryPostProcessor ,BeanFactoryPostProcessors// Register bean processors that intercept bean creation.// 从BeanFactory找出扫描得到得BeanPostProcessor,实例化并注册到BeanFactory中registerBeanPostProcessors(beanFactory);// Initialize message source for this context.// 初始化MessageSource,如果配置了一个名字叫做“messageSource”的BeanDefinition// 就会把这个Bean创建出来,并赋值给ApplicationContext的messageSource属性// 这样ApplicationContext就可以使用国际化的功能了initMessageSource();// Initialize event multicaster for this context.// 设置ApplicationContext的applicationEventMulticasterinitApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.// 执行子类的onRefresh方法onRefresh();// Check for listener beans and register them.// 注册ListenerregisterListeners();// Instantiate all remaining (non-lazy-init) singletons.// 完成beanFactory的初始化(实例化非懒加载的单例bean)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();}}}
refresh方法是一个模板方法,不管哪个容器实现还是SpringBoot最终创建Bean都会走到这个里面. 可以说这个方法是重中之重.大家先大概有个印象.后面我还会陆续分享Bean的循环依赖了生命周期了事务等等.