spring源码涵盖的代码量非常多,本人深入追了很多,提炼几点要点,也是方便自己记忆。希望对您有所帮助,当然,本人还是希望并且建议您多深入源码的学习,这样对spring源码更理解也可以增强您的框架定制开发能力。

话不多说,直接开始,请坐稳!

一、spring的入口

1.1注解方式

public static void main(String[] args)   {
		// 加载spring上下文
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);

		Car car =  (Car) context.getBean("car");
		System.out.println(car.getName());
}

1.2xml方式

public static void main(String[] args) {
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:/beans/beans.xml");
		ctx.getBean("car");
	}

创建文件resources/beans/beans.xml

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<beans>
 </bean>
    <bean class="com..iocbean.Car" id="car" >
 </bean>

</beans>

二、进入AbstractApplicationContext.refresh(beanFactory)方法

注:在refresh之前还有一些方法,总结一句话就是扫描和注册配置类(ConfigurationClassPostProcessor等),如果你想看具体,请访问


 

三、进入refrsh(ioc,aop)

主要方法(当然不是说其它方法不重要,这里是说主要关注这两个,如果您还对其它方法感兴趣,也可以去深究)

//扫描bean定义

AbstractApplicationContext
#invokeBeanFactoryPostProcessors(beanFactory)

 

//实例化和初始化bean

AbstractApplicationContext

#finishBeanFactoryInitialization(beanFactory);

 

四、ioc原理描述

4.1 入口: new AnnotationConfigApplicationContext(MainConfig.class); 

4.2 进入构造函数注册配置类:

//注册一些内置的后置处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

4.3 进入AbstractApplicationContext#refresh() ,参考上面步骤三

  1. 扫描bean定义
  1.   走后置处理器ConfigurationClassPostProcessor#processConfigBeanDefinitions(registry)
  2. 走解析ConfigurationClassParser.parse(candidates): 对写了@componentScan(@compent,@service,@respository@controller),@import,@importResource,@bean的解析成为beanDefinition,放入beanDefinitionMap中。
  1. 进入实例化和初始化 :进入9大后置处理器(内含aop入口、循环依赖,aop代理对创建)详情

五、aop原理

配置类

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.hgli")
public class MainConfig {

    @Bean
    public Car getCar() {
        return new Car();
    }

}

 核心EnableAspectJAutoProxy

EnableAspectJAutoProxy==>@Import(AspectJAutoProxyRegistrar.class)

5.1 spring扫描bean定义的时候@Import的类都会被解析,最后生成bean对象被spring容器管理。

 

我们来看下AspectJAutoProxyRegistrar做了什么?

@EnableAspectJAutoProxy 为我们容器中导入了 AnnotationAwareAspectJAutoProxyCreator,它实现了InstantiationAwareBeanPostProcessor接口

springframework源码的注释在哪看 spring源码解读_xml

5.2 InstantiationAwareBeanPostProcessor接口也就是bean实例化前经过的第一个后置处理器

InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation(beanClass, beanName);这个方法里进行aop解析

5.3 因为实现了BeanPostProcessor接口,在bean初始化后,会走postProcessAfterInitialization方法进行动态代理创建

BeanPostProcessor#postProcessAfterInitialization(result, beanName);

这就是aop的原理,其实就是首先要熟悉ioc对bean对象的解析创建流程。

六、事务原理

我们上面了解了aop原理,事务也是实现了aop,但是在启动类上我们还需要加另外一个注解@EnableTransactionManagement

@EnableTransactionManagement
	@EnableAspectJAutoProxy(exposeProxy = true)
	@ComponentScan(basePackages = {"com.hgli"})
	public class MainConfig {

    @Bean
    @Lookup
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        dataSource.setUrl("jdbc:mysql://localhost:3306/spring-trans");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        return dataSource;
    }
   }

核心@EnableTransactionManagement的讲解

可以参考

 

以上是本人对spring源码的总结,如果有错误之处,请不吝指出。

如果对您启到一点点帮助,请在下面点个小小的赞,给予我一点点鼓励,非常感谢!!