什么是Spring?
Spring在我们日常开发项目中可以说是基本上离不开了,而Spring从2.x版本到5.x版本,由单独IOC以及AOP发展到现在的一套spring生态(springcloud),受到广大程序员的青睐。
*解释:
Spring框架是 Java平台的一个开源的全栈应用程序框架和控制反转容器实现,一般被直接称为Spring。该框架的一些核心功能理论上可用于任何Java 应用,但Spring 还为基于Java企业版平台构建的Web 应用提供了大量的拓展支持。
自己的理解:
- Spring它是一个轻量级的框架,主要用于开发Java应用。
- Spring是一款软件的半成品,框架目的本身是简化Java企业级应用开发。
Spring能解决哪些问题?
- 从面向对象(静态)角度思考(面向对象分析构建)
- 对象的创建(在没框架之前,我们创建对象都是通过手动进行new出来,而Spring的IOC就能帮我们解决)
- 对象的管理(对象都是存储在内存的堆中,倘若对对象没有进行科学的管理则可以造成内存泄漏问题,多个对象内存泄漏就会导致内存溢出(创建对象的速度大于对象销毁速度)问题)
- 对象依赖注入(对象由spring来创建,需要对象使用的时候,spring将对象赋值给应用程序的过程称为依赖注入,对象与对象之间是存在依赖关系的)
- 从面向切面(动态)的角度思考(不改变原有代码的前提下,去扩展新的功能)
- 对象的功能扩展(业务需求的不断变更修改)
- 从项目架构的角度分析
- MVC分层架构,mould、视图层、控制层
- 面向服务(粒度)的角度思考(一个系统由多个微服务构建,分布式部署)
- 对象的粒度问题(微服务)
spring的核心组件?
- IOC容器(控制反转器):对象的创建、对象的存储、对象的注入
- WEB组件(重点解决MVC中细节问题–>处理请求,处理响应)
- AOP组件(重点解决对象扩展问题)
- Data组件(整合jdbc,整合mybatis)
spring核心架构?
Spring最初的目标就是要整合一切优秀的资源,如何对外提供一个统一的服务。
spring的架构图(spring4.0):
spring IOC简介
Spring 中有一个核心容器,这个容器我们通常称之为IOC容器,这个容器最核心功能就是控制反转。这个容器负责对象的创建,对象的存储(map),对象的管理(依赖查找,依赖注入)。
IOC容器如何实现?
1.1 容器如何知道创建哪些对象
通过xml或者注解的方式描述要创建的对象
1.2 容器如何构建这些类的对象
通过反射技术,Class.forName(" ")
1.3 容器如何存储对象
通过Map容器存储
1.4 IOC最大优势和劣势?
优势:
- 无需从新编译,只需要配置
- 更好的使用内存,防止内存泄漏(通过Map进行存储)
- 更好的解耦和(接口与接口之间的调用,如controller调service接口)
劣势:
- 构建对象过程变复杂(从原本的new变成需要添加注解和配置文件写容器存储等…)
- 对象结构可读性降低了(如:接口调用接口时不知调用的是哪个实现类)
spring IOC构建
<beans default-lazy-init="true">
<bean id="helloService" class="com.beans.HelloService">
<beans>
public class HelloService{
public void sayHello(){
System.out.println("hello spring");
}
}
public static void main(String[] args){
/** 传统方式 */
HelloSerivce hello = new HelloService();
hello.sayHello();
/** Spring IOC方式 */
1.初始化spring容器(此时不会调用该类的构造方法,也就是不会创建对象,将beans里面的default-lazy-init="true"延迟加载去除,则会在初始化容器时创建该对象)
ApplicationContext app = new ClassPathXmlApplicationContext("spring-configs.xml");
//ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-configs.xml");
2.获取Bean对象
HelloService service = app.getBean("helloService", HelloService.class);
3.使用Bean对象
service.sayHello();
4.释放资源
//context.close();
}
Spring Bean对象的管理
1.1 Bean 对象基本配置
在软件应用中由spring管理的所有对象都称之为bean。我们自己创建的类,假如需要spring管理,首先对这个类进行配置,常用的配置有两种,一种基于xml配置,另一种基于注解进行配置。
基于xml方式对象bean对象进行配置时,首先需要在spring的核心配置文件中,使用bean标签对象bean类型进行声明,借助id或者name属性指定bean的唯一标识,通过class属性指定bean的具体类型(类名必须写全类路径名)
<bean id="helloService" class="com.beans.HelloService"/>
<!-- 或者 -->
<bean name="helloService" class="com.beans.HelloService"/>
1.2 Bean对象的构建
- 通过构造方法
- 通过静态工厂方法(例如:Calendar的getInstance静态方法)
- 通过实例方法(例如:通过Calendar对象的getTime方法获取Date对象)
【注意】:以上无论通过哪种哪种方式构建对象,底层都会用到反射
spring-config.xml
<!-- 1.直接通过类的构造方法构建对象 -->
<bean id="date" class="java.util.Date"/>
<!-- 2.该bean无法构建初始化对象,因为这个类是抽象方法 -->
<bean id="calendar" class="java.util.Calendar"/>
<!-- 正确写法:通过该类的getInstance静态工厂方法构建对象 -->
<bean id="calendar" class="java.util.Calendar" factory-method=“getInstance”/>
<!-- 3.通过Calendar对象的getTime方法获取date对象。calendar表示引用上面的calendar bean, getTime方法表示调用Calendar对象的getTime方法 -->
<bean id="date" factory-bean="calendar" factory-method="getTime"/>
单元测试test
@junit
public class test{
private ClassPathXmlApplicationContext app;
@Before
public void init(){
app = new ClassPathXmlApplicationContext("spring-config.xml")
}
@Test
public void testCalendar(){
//Calendar cal = Calendar.getInstance();
Calendar cal = app.getBean("calendar", Calendar.calss);
}
@Test
public void testDate(){
Date date = app.getBean("date", Date.class)
}
@After
public void closeTest(){
app.close();
}
}
1.3 Bean对象的作用域
在spring容器中管理Bean对象,可以声明时通过scope属性或相关注解指定其作用域,最常见是singleton,prototype,其含义如下:
- singleton:这个作用域标识的对象具备全局唯一性(系统默认)
- prototype:这个作用域标识的对象每次获取都会创建新的对象
<!-- 此时在测试类中getBean获取该对象时,只会调用该类的一次构造方法 -->
<bean id="helloService" class="com.beans.HelloService" scope="singleton"/>
<!-- 此时在测试类中getBean获取该对象时,会调用该类的多次构造方法 -->
<bean id="helloService" class="com.beans.HelloService" scope="prototype"/>
HelloService类
public class HelloService{
public HelloService(){
System.out.println("helloService()")
}
}
单元测试test
@Test
publilc void testHelloService(){
HelloService helloService = app.getBean("helloService", HelloService.class);
helloService = app.getBean("helloService", HelloService.class);
}
控制台输出
当bean的scope=“singleton”
helloService()
当bean的scope=“prototype”
helloService()
helloService()
1.4 spring Bean的生命周期
在spring框架应用中,所有的bean对象都有生命周期,所谓bean对象的生命周期是指Bean对象的创建、初始化、服务、销毁这个过程。
在spring配置文件中可以通过init-method,destory-method属性指定bean对象的生命周期。
在spring应用由spring创建的对象是否有spring销毁,还取决于作用域的配置。例如:
- singleton作用域的对象可以在容器关闭是销毁。
- prototype作用域对象可以有容器创建对象,初始化对象,但不负责销毁。
spring-config.xml
<!-- 当scope=“singleton时,destory方法不会执行,因为对象是唯一的,只有将容器close后才会执行destory方法” -->
<bean id="helloService" class="com.beans.HelloService" scope="singleton" init-method="init" destroy-method="destory"/>
HelloService类
public class HelloService{
//getbean获取对象时执行
public HelloService(){
System.out.println("helloService()")
}
//创建对象之后执行
public void init(){
System.out.println("init()")
}
//服务
public void sayHello(){
System.out.println("sayHello()")
}
//销毁对象时候执行
public void destory(){
System.out.println("destory()")
}
}
单元测试类
@Test
publilc void testHelloService(){
HelloService helloService = app.getBean("helloService", HelloService.class);
helloService.sayHello();
}
@After
public void close(){
//当scope=“singleton”时,只有关闭资源,才能调用HelloService的destory()方法
//app.close();
}
控制台输出
helloService()
init()
sayHello()
正在持续更新中…