今日分享开始啦,请大家多多指教~
Spring是什么?
-
Spring是什么呢?我们可看一下官网的定义:
-
Spring快速、容易、安全,专注速度,开发效率高,Spring是全世界最流行的Java开发框架。
Spring Framework框架
Spring Framework是Spring中的核心框架,结构如下所示:
Core Container(核心容器)模块主要是四部分构成:
-
Sping-Beans
-
Spring-Core
-
Spring-Context
-
Spring-Expression Language
1.IoC容器
IoC(Inversion of Control)称为控制反转,是面向对象编程中的一种设计原则,主要用来降低代码之间的高耦合度问题。
从使用上看,使用IoC之前,创建对象需要手动new对象,并设置对象属性,控制权掌握在应用程序自身(对象的创建与销毁都掌握在我们自己手中);使用IoC之后,对象的控制权交给了第三方进行管理,这里的第三方就是容器,因而对象由容器来管理。因为发生了控制权的反转,所以叫控制反转。
2.DI(依赖注入)
DI(Dependency)称为依赖注入,是实现IoC的方法之一,所谓依赖注入就是指IoC容器运行期间,动态地将某种依赖关系注入到对象到中。
3.IoC与DI关系
实际上,IoC与DI是从不同角度描述的同一件事情,当引入IoC容器后,使用依赖关系注入的方式,实现了对象之间的解耦。
接下来主要针对Sping-Beans与Spring-Context进行介绍:
Spring容器的API有BeanFactory和ApplicationContext两大类,二者都是顶级接口,其中ApplicationContext是BeanFactory的顶级接口。接下来的代码演示部分,我们都基于ApplicationContext应用上下文接口去实现容器。
我们先基于Maven创建Spring项目,具体步骤如下:
1.创建Maven项目后,在pom.xml配置文件中引入外部依赖,刷新Maven面板
2.准备项目启动类入口
将beans.xml文件作为参数对ClassPathXmlApplicationContext类进行实例化操作,构建一个ApplicationContext对象。
3.定义Spring配置文件(这里指的就是beans.xml)
在src/main/resources/下创建beans.xml文件,写入内容
<context:component-scan base-package="org.example"/>
base-package:表示的是Spring启动时候扫描的包路径,该路径下带有类注解的类将被注册到容器里。
4.扫描Spring类注解注册Bean对象
类注解方式:共有4种类注解,它们虽然对应不同的业务,但是都是为Spring容器服务的;类注解定义方式默认会注册类名首字母小写的Bean对象到容器中。
@Controller :前端业务交互(参数校验)
@Service :业务处理中间类(业务逻辑处理)
@Repository :数据持久层(增删查改)
@Component :通用对象工具类(比如数据序列化、反序列化操作)
5.得到容器中Bean对象
第一种得到Bean对象方式:
需要特别注意的是:getBean方法中的参数首字母一定是小写的(源码表示启动类名首字母小写),否则代码引发异常。
第二种得到Bean对象方式:
从代码执行的结果可以看出:Bean对象被正常打印出来
两种方式拿到的对象是否一样呢?
从结果可以看出两种方式获得的对象是同一个Bean对象,这是因为Spring使用了单例模式。
特殊情况:当注解类前两个字母都为大写时,传入的参数为原来的类名
从代码执行结果来看,此时getBean方法传入的参数要求是原来的类名。
Lombok依赖
当在beans.xml中添加了Lombok依赖时,需要安装Lombok插件
Lombok使用演示:
对上面代码build操作后,可以发现自动生成了三种方法
Lombok原理:它是自定义注解的方式,在代码编译时期,将自定义的注解更换成了JVM可以执行的方法(就是get、set、toString方法)。
注册Bean的方式
1.类注解
上面已经阐述,此处不再赘述。
2.@Bean注解
当前类被Spring扫描时,可以在方法上使用@Bean注解,通过方法返回类型,可以定义、注册Bean对象,默认使用方法名作为Bean的名称。
在LoginController中定义两个User方法:
从结果可以看出@Bean方法注解成功注册了Bean对象。
那么能不能以同样的方式(或者Use.class方式)传入user2拿到Bean对象?
答案:不行,因为user1和user2方法返回的都是User类型,容器中注册的Bean对象有两个。
如何得到user2的Bean对象呢?
首先在LoginController类上加入Getter注解。
3.@Configuration注解
当类被Spring扫描时,使用@Configuration注解,可以注册一个配置类到容器中,配置类一般用来自定义配置某些资源。
从结果可以看出,使用Configuration注解注册了Bean对象。
依赖注入的方式
1.属性注入
结果说明在LoginController类中,通过属性注入的方式,可以得到Bean对象。
2.set方法注入
3.构造方法注入
三种注入方式比较来看,属性注入的方式是最简洁的。
4.指定注入:@Qualifier
当同类型的Bean有多个时,注入该类型Bean需要指定Bean的名称:
属性名或方法参数名设置为Bean的名称;
属性名或方法参数设置@Qualifier(“名称”)注解,注解内的字符串是Bean对象的名称。
Bean的作用域
Spring容器在初始化一个Bean对象时,同时会指定该对象的作用域,一共有6种作用域,接下来我们分别来看:
1.singleton
该作用域为单例模式作用域,Bean在IoC容器中只有一个实例对象,获取Bean(getBean)以及装配Bean(@Autowired)都是同一个对象。Spring容器默认默认选择的是singleton作用域。
2.prototype
每次该作用域下Bean的请求都会创建新的实例,也就是说每一次的获取Bean和装配Bean都是新的对象。通常有状态的Bean使用该作用域。
3.request
每次http请求都会创建新的Bean实例;适用场景:一次http请求和响应的共享Bean;限定在SpringMVC中使用。
4.session
在一个http的session中定义一个Bean实例;场景:http的session会话中记录一个用户的登录信息;限定在SpringMVC中使用。
5.application
在一个http servlet Context中,定义一个Bean实例;场景:Web应用的全局上下文信息,比如记录一个应用的共享信息;限定在SpringMVC中使用。了解即可
6.websocket
在一个http WebSocket的生命周期中,定义一个Bean实例;场景:WebSocket的每次会话中,保存了一个Map结构的头信息,用来包裹客户端的消息头,第一次初始化后,直到WebSocket结束都是一个Bean;限定在Spring WebSocket中使用。
Bean生命周期
生命周期图
Bean的生命周期主要步骤:
1.实例化Bean:通过反射机制调用构造方法实例化对象;
2.依赖注入:装配Bean的属性;
3.实现了Aware接口的Bean,执行接口的方法:顺序执行BeanNameAware、BeanFactoryAware、ApplicationContextAware的接口方法;
4.Bean对象初始化之前,循环调用实现了BeanPostProcessor接口的预初始化方法postProcessBeforeInitialization;
5.Bean对象初始化:顺序执行@PostConstruct注解方法、InitializingBean接口方法、init-method方法;
6.Bean对象初始化后,循环调用实现了BeanPostProcessor接口的后初始化方法
postProcessAfterInitialization;
7.容器关闭时调用Bean对象的销毁方法,顺序:@PreDestroy注解方法、@DisposableBean接口方法、destory-method。
今日份分享已结束,请大家多多包涵和指点!