初探Spring(一)

初探Spring(一)

吃的苦中苦,方为人上人


前言

1.Bean的生命周期底层原理
2.依赖注入
3.初始化
4.推断构造方法
5.AOP
6.spring事务


以上6点我认为是spring框架的核心点

一、spring入门?

首先来看看spring入门使用的代码。

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) context.getBean("userService");
userService.test();

对于这三行代码其实大多数人都是比较熟悉的,这个其实就是spring的Hello Word 可是这三行都做了什么呢?一起来看一下

  • 一、第一行代码,构造了一个ClassPathXmlApplicationContext对象,ClassPathXmlApplicationContext该如何理解,调用该构造方法除了会实例化一个对象,还会做什么?

  • 二、第二行代码,调用了ClassPathXmlApplicationContext的getBean方法,会得到一个UserService对象,getBean()是如何实现的?返回的UserService对象和我们直接new出来的UserService对象又有什么区别?

  • 三、第三行代码就是调用了UserService的一个test方法,这个不难理解。

二、Spring只是这样吗?

光看这三行代码其实并不能体现出来Spring的强大之处,也不能理解为什么要使用ClassPathXmlApplicationContext和getBean方法,随着慢慢深入的了解将会消除你心中的疑问。
但是使用ClassPathXmlApplicationContext这种方式已经过时了,在新版的Spring Boot底层主要使用的是AnnotationConfigApplicationContext 比如

代码如下(示例):

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
//ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) context.getBean("userService");
userService.test();

可以看到AnnotationConfigApplicationContext跟ClassPathXmlApplicationContext这种方式使用非常类似只不过前者使用的是class文件 后者使用的是xml这种方式。但其实这两者都是一样的都是表示的spring的配置只不过形式不同
(例如spring.xml):

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

(例如AppConfig):

@ComponentScan("com.app")
public class AppConfig {

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

}

2.spring是如何创建对象的

其实不管是那种形式,目前我们都可以把他理解为都是用来创建java对象的,比如调用getBean()就是来创造对象的(不是很严谨闲这样理解)在java中肯定是根据一个类来创造对象的

代码如下(示例):

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService) context.getBean("userService");
userService.test();

当我们去context.getBean(“userService”);时,就回去创建一个对象,但是getBean方法内部是怎么知道“userService”对应的是UserService这个类呢?
所以我们就可以分析出来,在调用AnnotationConfigApplicationContext这个的时候也就是第一行代码可能要做一些事情。

  • 解析AppConfig.class方法,得到扫描的路径

  • 遍历所有的java类,如果发现某些方法上面有@Component、@Service等注解,那么spring就把这些类记录下来存到一个map中去,比如Map<String,
    Class>。(实际上,Spring源码中确实存在类似的这么一个Map,叫做BeanDefinitionMap

  • spring会根据某个规则生成当前类对应的beanName,作为Key存到map中去,当前类做为这个key的value.

这样,但调用context.getBean(“userService”)时,就可以根据"userService"找到UserService类,从而就可以去创建对象了。​

3.bean创建的过程

spring到底是如何创建bean的呢?这个其实就是bean的生命周期的过程

  • 利用该类的构造方法去实例化一个对象,但是其实一个类中会有多个构造方法,(这个其实就是推断构造方法,spring会选择)
  • 得到一个对象之后,spring会判断该对象中是否存在被@Autowired注解的属性把这些属性进行赋值(依赖注入)
  • 依赖注入后,Spring会判断该对象是否实现了BeanNameAware接口、
    BeanClassLoaderAware接口、BeanFactoryAware接口,如果实现了,就表示当前对象必须要实现该接口中所定义的setBeanName()、setBeanClassLoader()、setBeanFactory().那么spring就会调用这些方法(Aware回调)
  • Aware回调后,spring会判断该对象中的是否存在某个方法被@PostConstruct注解了,如果存在,spring会调用当前对象的此方法(初始化前)
  • 紧接着,Spring会判断该对象中的某个方法被@PostConstruct 注解了,如果存在,spring会调用当前对象的此方法(初始化前)
    -紧接着,spring会判断该对象是否实现了InitializingBean接口,如果实现了,就表示当前对象必须实现 该接口中的afterPropertiesSet()方法,那么spring就会调用当前对象中的afterPropertiesSet()方法(初始化)
    -最后,如果spring会判断当前对象需不需要进行AOP,如果不需要那么bean就创建完了,如果需要进行aop,则会进行动态代理创建一个代理对像作为Bean(初始化后)
  • 通过最后一步我们可以发现,当spring根据UserService类来创建一个bean的时候:
  • 1.如果不用进行AOP那么Bea就是UserService类构造方法所得到的对像。
  • 2.如果需要进行AOP,那么bean就是UserService的代理类所实例化的对象,而不是UserService本身所得到的对像。
  • bean创建出来对象后:
  • 1.如果当前bean是单例的那么会给他存到一个map<String,Object>中,map对应的是beanName,value为bean的对象,这样下次获取bean的时候就直接可以直接从map中获取到bean的对象了,
  • 2.如果bean是多例的,那么就不会存到这个map中,每次拿的时候就会创建一个新的bean。(重新执行上述创建的过程)

3.bean创建的过程

该处使用的url网络请求的数据。


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值