Spring源码学习(从入门到放弃~~~持续更新)

Spring源码学习

从入门到入坟,从加载第一个Bean说开去,本篇博文只是简单的说明一下Spring的核心原理,后续会持续更新更加详细的内容~~~


ps:如果有分歧,请在评论区留言~~


前言

本人也是小白开发,目前从事开发2年希望通过本文可以学习更多的知识


提示:以下是本篇文章正文内容,下面开始

一、从Spring使用方式开始扯~

传统的加载spring配置文件如下,

	//通过加载spring.xml
	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

	UserService userService = (UserService) context.getBean("userService");

<context:component-scan base-package="com.laoyang"/>
<bean id="userService" class="com.zhouyu.service.UserService"/>

现在更推荐使用如下的加载方式;

	//通过AppConfig.Class方式加载
	AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
	
	UserService userService = (UserService) applicationContext.getBean("userService");
@ComponentScan("com.laoyang")
public class AppConfig {

	@Bean
	public UserService userService(){
		return new UserService();
	}

}

通过上面的两行代码,我们知道了Spring是如果加载配置文件和如何得到了第一个Spring的Bean
现在有两个疑问:
1.ClassPathXmlApplicationContext 和 AnnotationConfigApplicationContext 的构造方法除了加载出一个context的类之外,还做了哪些事情;
2.getBean得到的Bean和我们普通 new 出来的对象有何区别?
带着疑问,继续往下走

二、Spring是如何创建对象的?

1.分析构造方法

其实,不论是通过xml还是通过java文件来加载配置,其作用看起来都是用来创建Bean的,通过getBean()来创建Bean(这里是不严谨的,如果是原型bean是创建,如果是单例,这里只是取出,而不是创建),我们通过

UserService userService = (UserService) applicationContext.getBean("userService");

来得到userService,但是Spring是如何知道哪个类是userService呢?我们可以推断,在加载配置文件的时候,Spring会扫描某个路径,得到某些类的全限定类名.
而事实上,Spring确实是这么干的,它会扫描某些包,把其中的单例类,保存在一个Map<k,v> 中,k是类的名字,v是这个类的class,(而原型bean,是随用随取(创建),不参与bean的生命周期)
这样,在getBean()的时候就可以从map中获取bean了

2.Bean的创建过程,与我们new的对象有何区别?

Spring创建Bean的过程,也就是Bean的生命周期:
大致如下:
1.实例化对象(这个过程Spring会利用这个类的构造方法,实例化一个对象,如果有多个构造方法,spring会进行判断,这个叫做推断构造方法);
2.进行属性的注入(依赖注入),根据@Autowired等进行属性的填充;
3.进行Aware回调,如果实现了BeanNameAware接口、BeanClassLoaderAware接口、BeanFactoryAware接口,Spring会重写setBeanName()、setBeanClassLoader()、setBeanFactory()方法,那Spring就会调用这些方法并传入相应的参数;
4.回调完成后,如果某个对象的某个方法被标注了@PostConstruct注解,那么Spring会在初始化之前调用这个类的这个方法(初始化前),
5,如果这个类实现了InitializingBean接口,会调用afterPropertiesSet()方法(初始化)
6.此时,Spring会判断这个对象是否需要AOP.如果不需要的话,此时Bean就可以使用了.如果需要,Spring就会通过动态代理生成一个代理对象作为这个Bean(初始化后)

我们自己new 的对象是不会经过如上流程的.~

3.Spring的AOP

Spring是如何判断某个对象是否需要AOP呢
1.在初始化的过程中,Spring会找出所有的切面Bean,看看是否写了@Before等注解
2.如果有这些注解,会判断Pointcut是否和当前Bean匹配,如果匹配就生成这个Bean的代理对象,表示需要进行AOP

Spring默认使用的是Cglib动态代理,具体流程如下
1.生成代理类UserServiceProxy,代理类继承UserService
2.代理类中重写了父类的方法,比如UserService中的test()方法
3.代理类中还会有一个target属性,该属性的值为被代理对象(也就是通过UserService类推断构造方法实例化出来的对象,进行了依赖注入、初始化等步骤的对象)
4.代理类中的test()方法被执行时的逻辑如下:
a.执行切面逻辑(@Before)
b.调用target.test()

AOP失效的场景
其实判断AOP是否失效很简单,看执行当前方法的是AOP的代理对象还是原对象,如果是原对象,那么这个AOP是失效的,比如,在一个没有进行AOP的方法里面调用一个进行AOP的方法,或者在AOP的方法里面调用另外一个AOP方法,都会使AOP失效,
解决办法:
在当前类注入当前类,(自己注入自己),就可以获得spring生成的bean啦就可以完美解决~!


总结

例如:以上就是今天要讲的内容,本文仅仅简单介绍了Spring的Bean的生命周期,而Spring的内容远远不止如此,每天分享一丢丢spring的知识,共同进步~!,谢谢收看,
下集预告:
手写Spring部分功能,为研究spring源码做好充分的准备~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值