1、Spring概述
官网:https://spring.io
文档地址:https://docs.spring.io/spring-framework/docs/current/reference/html/
老版文档地址:https://docs.spring.io/spring-framework/docs/4.3.25.RELEASE/spring-framework-reference/html/
中文文档:https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference/
项目地址:https://github.com/spring-projects/spring-framework
Spring 是一款轻量级、非侵入式的开源框架,它由Rod Johnson于 2002 年提出并随后创建(最初版本是interface21)。
目的:为了简化Java企业级应用程序开发的复杂度(简单来讲是解耦合)。
Spring的两大特性:IOC、AOP。
-
IOC:(全称:Inverse of Control )控制反转,指把创建对象过程交给 Spring 进行管理。
-
AOP:(全称:Aspect Oriented Programming )面向切面编程,
AOP 用来封装多个类的公共行为,将那些与业务无关,却为业务模块所共同调用的逻辑封装起来,减少系统的重复代码,降低模块间的耦合度。另外,AOP 还解决一些系统层面上的问题,比如日志、事务、权限等。
Spring可以和许多优秀的框架整合。
Spring的生态:
-
Spring Framework(是其他子项目的基础)
-
Spring MVC( Web应用开发)
-
SpringBoot(它为 Spring 以及第三方库提供一些开箱即用的配置,简化 Spring 应用的搭建及开发过程)
-
Spring Cloud(基于 Spring Boot 实现的微服务框架。它并不是某一门技术,而是一系列微服务解决方案或框架的有序集合。它将市面上成熟的、经过验证的微服务框架整合起来,并通过 Spring Boot 的思想进行再封装,屏蔽掉其中复杂的配置和实现原理,最终为开发人员提供了一套简单易懂、易部署和易维护的分布式系统开发工具包)
-
Spring Data (数据访问模块,对JDBC和ORM提供了很好的支持。通过它,开发人员可以使用一种相对统一的方式,来访问位于不同类型数据库中的数据)
-
Spring Security (前身 Acegi,是 Spring 中较成熟的子模块之一,它是一款可以定制化的身份验证和访问控制框架)
…
2、第一Spring应用程序
1、创建一个普通的Maven工程
2、导入依赖
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.15</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
3、编写实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private int id;
private String name;
private String pwd;
public Student(String name, String pwd) {
this.name = name;
this.pwd = pwd;
}
}
4、创建一个Spring配置文件:applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- bean:就是java对象 , 由Spring创建和管理
id:唯一标识,用于我们之后给属性赋值
class:指的是我们为哪个类创建实例
-->
<bean id="student" class="com.baidou.pojo.Student">
<property name="id" value="1001"></property>
<property name="name" value="白豆五"></property>
<property name="pwd" value="123456"></property>
<!--属性可以引用另外一个bean , 用ref方式 -->
<!--<property name="xxxXXX" ref="xxx"/>-->
</bean>
</beans>
5、编写测试
public class ApplicationTest {
@Test
public void test1() {
// 获取Spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 通过id获取容器中的Bean
Student student = (Student) context.getBean("student");
System.out.println(student);
}
}
控制台输出结果如下:
最后项目结构如下:
3、Spring IoC
控制反转(Inversion of Control ,简写为:IoC)它并不是一门技术,而是一种设计思想,是一个重要的面向对象编程法则,能够指导我们如何设计出松耦合、更优良的程序。
Spring 通过 IoC 容器来管理所有 Java 对象的实例化和初始化,控制对象与对象之间的依赖关系。我们将由 IoC 容器管理的 Java 对象称为 Spring Bean,它与使用 new关键字 创建的 Java 对象没有任何区别。
IoC 容器是 Spring 框架中最重要的核心组件之一,它贯穿了 Spring 从诞生到成长的整个过程。
依赖注入(Denpendency Injection,简写为: DI)是 Martin Fowler 在 2004 年在对 “控制反转” 进行解释时提出的。Martin Fowler 认为 “控制反转” 一词很晦涩,无法让人很直接的理解 “到底是哪里反转了” ,因此他建议使用 “依赖注入” 来代替 “控制反转” 。
在面向对象中,对象和对象之间是存在一种叫做 “依赖” 的关系。简单来说,依赖关系就是在一个对象中需要用到另外一个对象,即对象中存在一个属性,该属性是另外一个类的对象。
3.1、基于XML配置使用IoC
开发者把需要的对象在XML中进行配置,然后Spring框架读取这个配置文件,根据配置文件的内容来创建对象。
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!--配置自定义的Bean-->
<bean id="student" class="com.baidou.pojo.Student">
<property name="id" value="1001"></property>
<property name="name" value="白豆五"></property>
<property name="pwd" value="123456"></property>
</bean>
</beans>
public class ApplicationTest {
@Test
public void test1() {
// XML解析的方式创建Spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
// 通过id获取容器中的Bean
Student student = (Student) context.getBean("student");
System.out.println(student);
}
}
3.2、基于注解使用IoC
配置类
通过一个 配置类 来替代 XML 配置文件中的内容。
package com.baidou.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BeanConfiguration {
@Bean(name = "student")
public Student getStudentBean(){
return new Student(1002,"李四","lisi666");
}
}
public class ApplicationTest {
@Test
public void test1() {
// 1、指定配置类的方式
// ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfiguration.class);
// 2、扫描包的方式
ApplicationContext context = new AnnotationConfigApplicationContext("com.baidou.configuration");
Student student = (Student) context.getBean("student");
System.out.println(student);
}
}
扫包+注解的方式
不再需要依赖于 XML 或者配置类,而是直接 将 bean 的创建交给目标类,然后在目标类中添加注解。
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component //将这个类注入到IOC容器中
public class Student {
@Value("1003")
private int id;
@Value("王五")
private String name;
@Value("wangwu666")
private String pwd;
public Student(String name, String pwd) {
this.name = name;
this.pwd = pwd;
}
}
public class ApplicationTest {
@Test
public void test2() {
ApplicationContext context = new AnnotationConfigApplicationContext("com.baidou.pojo");
Student student = (Student) context.getBean(Student.class);
System.out.println(student);
}
}
使用@Autowired 注解完成依赖注入:
@Data
@Component
public class Clazz {
@Value("2018")
private int id;
@Value("计科")
private String clazzName;
@Autowired //依赖注入
private Student student;
}
public class ApplicationTest {
@Test
public void test3() {
ApplicationContext context = new AnnotationConfigApplicationContext("com.baidou.pojo");
Clazz clazz = (Clazz) context.getBean(Clazz.class);
System.out.println(clazz);
}
}
如果需要通过指定的名称取值, 使用@Qualifier 注解完成名称的映射:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component("stu") //将这个类注入到IOC容器中
public class Student {
@Value("1003")
private int id;
@Value("王五")
private String name;
@Value("wangwu666")
private String pwd;
public Student(String name, String pwd) {
this.name = name;
this.pwd = pwd;
}
}
@Data
@Component
public class Clazz {
@Value("2018")
private int id;
@Value("计科")
private String clazzName;
@Autowired //@Autowired注解会通过类型去依赖注入
@Qualifier("stu")
private Student student;
}
public class ApplicationTest {
@Test
public void test3() {
ApplicationContext context = new AnnotationConfigApplicationContext("com.baidou.pojo");
Clazz clazz = (Clazz) context.getBean(Clazz.class);
System.out.println(clazz);
}
}