一文入门Spring
Posted itLaity
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一文入门Spring相关的知识,希望对你有一定的参考价值。
生命无罪,健康万岁,我是laity。
我曾七次鄙视自己的灵魂:
第一次,当它本可进取时,却故作谦卑;
第二次,当它在空虚时,用爱欲来填充;
第三次,在困难和容易之间,它选择了容易;
第四次,它犯了错,却借由别人也会犯错来宽慰自己;
第五次,它自由软弱,却把它认为是生命的坚韧;
第六次,当它鄙夷一张丑恶的嘴脸时,却不知那正是自己面具中的一副;
第七次,它侧身于生活的污泥中,虽不甘心,却又畏首畏尾。
一、Spring说明
Spring框架是由于软件开发的复杂而创建的
Spring对速度、简单性和成产率的关注使它称为世界上最流行的Java框架
- 微服务开发 (Microsevices)
- web开发(web apps)
- 分布式开发(spring cloud)
Spring 是一个大家族
Spring全家桶
- Spring Framwork
- Spring Boot
- Spring Cloud
- Spring MVC
- …
官网地址
https://spring.io/
二、Spring Framework
特征
- 核心技术:依赖注入、事件、资源、i18n、验证、数据绑定、类型转换、SpEL、AOP。
- 测试:模拟对象、TestContext 框架、Spring MVC 测试、
WebTestClient
. - 数据访问:事务、DAO 支持、JDBC、ORM、Marshalling XML。
- Spring MVC和 Spring WebFlux Web 框架。
- 集成:远程处理、JMS、JCA、JMX、电子邮件、任务、调度、缓存。
- 语言:Kotlin、Groovy、动态语言。
Spring 架构
核心容器
Core Container
- Ioc控制反转
- 使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转换到外部,此思想称为控制反转。
- Spring技术对IoC思想进行了实现
- Spring提供了一个容器,称为IoC容器,用来充当IoC思想中的外部
- IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为 Bean
- DI 依赖注入
- 在容器中建立Bean与Bean之间的依赖关系的整个过程,称为依赖注入。
数据访问
Data Access/Integration
面向切面编程
AOP
AOP
思想的实现
Aspects
事务
Transactions
三、Spring IoC
3.1 Spring框架部署(IoC)
3.1.1 创建Maven项目
- Java
- Web
3.1.2 添加SpringIoC依赖
- core
<!-- spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.13</version>
</dependency>
- beans
<!-- spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.13.RELEASE</version>
</dependency>
context
<!-- spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
- aop
- 导入 context 直接携带导入
- expression
- 导入 context 直接携带导入
3.1.3 创建Spring配置文件
通过配置文件 “告诉” Spring 容器创建什么对象,给对象属性 赋什么值
-
在resources目录下创建名为:
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" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--对于一个xml文件如果作为框架的配置文件,需要遵守框架的配置规则--> <!--通常一个框架为了开发者能够正确的配置,都会提供xml的规范文件(dtd\\xsd)--> <!--xsd 可以根据配置引入多个,只要引入了相应的xsd,可以使用相应标签规则属性--> </beans>
3.2 SpringIoc使用
使用SpringIoC组件创建并管理对象
3.2.1 创建一个实体类
3.2.2 在Spring配置文件中配置实体类
<!-- 通过bean 实体类配置给Spring进行管理 id表示实体类的唯一标识 -->
<bean id="student" class="com.laity.ioc.bean.Student">
<property name="stuNum" value="101"/>
<property name="stuName" value="laity"/>
<property name="stuAge" value="18"/>
</bean>
3.2.3 初始化Spring工厂,获取对象
public class Test1
public static void main(String[] args)
// 通过Spring容器创建Student对象
// 1.初始化spring容器,加载Spring配置文件。
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2.通过Spring容器获取 Student对象
Student student = (Student) context.getBean("student");
System.out.println(student);
3.3 IoC和DI
- IoC控制反转,依赖Spring对象工厂完成对象的创建。
- DI 依赖注入,在Spring完成对象创建的同时依赖Spring容器完成对象属性的赋值。
3.3.1 IoC
当我们需要通过Spring对象工厂,创建某个类的对象时,需要将这个交给spring容器来进行管理
3.3.2 DI
通过Spring容器 给创建的对象属性赋值
3.4 DI依赖注入
Spring容器加载配置文件后,通过反射创建类的对象,并给属性赋值
四、Spring配置数据源
4.1 数据源(连接池)的作用
- 数据源(连接池)是提高程序性能出现的
- 事先实例化数据源,初始化部分连接资源
- 使用连接资源时从数据源中获取
- 使用完毕后将连接资源归还给数据源
常用的数据源(连接池):DBCP、C3P0、BoneCP、Druid等
4.2 数据源开发步骤
- 导入数据源坐标和数据源驱动坐标
- 创建数据源对象
- 配置文件,设置基本连接数据
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
</dependencies>
4.3 抽取jdbc.properties文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///java?useSSL=false&useUnicode=true&characterEncoding=utf-8&useServerPrepStmts=true
user=root
password=wang9264
initialSize=5
maxActive=10
# useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
maxWait=3000
4.4 Spring配置数据源
<!-- Spring配置数据源 =====================================================-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///java?useSSL=false"></property>
<property name="user" value="root"></property>
<property name="password" value="wang9264"></property>
</bean>
name值 要与 方法名对应 例如:setDriverClass 写成 driverClass
4.5 Spring加载properties
<!-- 1. 先导入 context 规则-->
<?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"
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">
<!-- 2. 加载外部的properties文件 $key -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="$driverClassName"/>
<property name="jdbcUrl" value="$url"/>
<property name="user" value="$user"/>
<property name="password" value="$password"/>
</bean>
五、Spring注解开发
Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。
5.1 Spring的原始注解
主要代替 配置
- 在实现类上添加注解
package com.laity.service.impl;
import com.laity.dao.UserDao;
import com.laity.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
/**
* @author: Laity
* @Project: JavaLaity
* @Package: com.laity.service.impl.UserServiceImpl
* @Date: 2022年05月26日 19:59
* @Description:
*/
//<bean id="userService" class="com.laity.service.impl.UserServiceImpl">
//<property name="userDao" ref="userDao"/>
//</bean>
//@Component("userService") // 使用在类上用于实例化Bean
@Service("userService") // 使用在service层类上用于实例化Bean
public class UserServiceImpl implements UserService
//<property name="userDao" ref="userDao"/>
// @Autowired // 使用在字段上用于根据类型依赖注入
// @Qualifier("userDao") // 结合@Autowired一起使用用于根据名称进行依赖注入
@Resource(name = "userDao") // 相当于 @Autowired + @Qualifier
private UserDao userDao;
// xml 方式需要使用set方法
// 注解的方式 set方法可以不需要有
public void setUserDao(UserDao userDao)
this.userDao = userDao;
@Override
public void save()
userDao.save();
package com.laity.dao.impl;
import com.laity.dao.UserDao;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
/**
* @author: Laity
* @Project: JavaLaity
* @Package: com.laity.dao.impl.UserDapImpl
* @Date: 2022年05月26日 19:57
* @Description:
*/
//<bean id="userDao" class="com.laity.dao.impl.UserDapImpl"></bean>
//@Component("userDao") // 使用在类上用于实实例Bean
@Repository("userDao") // 使用在dao层类上用于实例化Bean
public class UserDapImpl implements UserDao
@Override
public void save()
System.out.println("save running ...");
- 在 applicationContext.xml 中 配置扫描器
<!-- <bean id="userDao" class="com.laity.dao.impl.UserDapImpl"></bean>-->
<!-- <bean id="userService" class="com.laity.service.impl.UserServiceImpl">-->
<!-- <property name="userDao" ref="userDao"/>-->
<!-- </bean>-->
<!-- 配置组件扫描 : 扫注解 -->
<!-- 扫描 com.laity 下的所有包 -->
<context:component-scan base-package="com.laity"/>
5.2 Spring的新注解
上面的注解还不能全部代替xml配置文件,所以出现了新注解 – 达到全注解开发
注解 | 说明 |
---|---|
@Configuration | 用于指定当前类是一个 Spring 配置类,当创建容器时会从该类上加载注解 |
@ComponentScan | 用于指定Spring在初始化容器时要扫描的包。作用和在 Spring 的 xml 配置文件中的<context:component-scan base-package=“com.itheima”/>一样 |
@Bean | 使用在方法上,标注将该方法的返回值存储到 Spring 容器中 |
@PropertySource | 用于加载.properties 文件中的配置 |
@Import | 用于导入其他配置类 |
- Spring的核心配置文件:SpringConfiguration.class
package com.laity.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
import java.util.ResourceBundle;
/**
* @author: Laity
* @Project: JavaLaity
* @Package: com.laity.config.SpringConfiguration
* @Date: 2022年05月26日 22:08
* @Description: Spring的核心配置文件
*/
@Configuration // 标志 该类是Spring的核心配置文件
// <context:component-scan base-package="com.laity"/>
@ComponentScan("com.laity") // 代替扫描注解的作用
@Import(DataSourceConfiguration.class,)
public class SpringConfiguration
- 数据源配置文件:DataSourceConfiguration.class
package com.laity.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
/**
* @author: Laity
* @Project: JavaLaity
* @Package: com.laity.config.DataSourceConfigration
* @Date: 2022年05月26日 22:28
* @Description: 数据源 配置文件
*/
// <context:property-placeholder location="classpath:jdbc.properties"/>
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiguration
@Value("$driverClassName")
private String driverClassName;
@Value("$url")
private String url;
@Value("$user")
private String user;
@Value("$password")
private String password;
// 使用在方法上,标注将该方法的返回值存储到 Spring 容器中
@Bean("dataSource") // Spring会将当前方法的返回值 以 指定名称存储到Spring容器中
public DataSource getDataSource() throws Exception
/*
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="$driverClassName"/>
<property name="jdbcUrl" value="$url"/>
<property name="user" value="$user"/>
<property name="password" value="$password"/>
</bean>
*/
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driverClassName);
dataSource.setJdbcUrl(url);
// useSSL=false&useUnicode=true&characterEncoding=utf-8&useServerPrepStmts=true
dataSource.setUser(user);
dataSource.setPassword(password);
return dataSource;
- 修改测试文件:UserController.class
package com.laity.web;
import com.laity.config.SpringConfiguration;
import com.laity.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author: Laity
* @Project: JavaLaity
* @Package: com.laity.web.UserController
* @Date: 2022年05月26日 20:14
* @Description: 假的web层
*/
public class UserController
public static void main(String[] args)
// ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
UserService userService = app.getBean(UserService.class); // 一个Bean用类,多个的时候用 id
userService.save();
六、Spring整合Junit
让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉Junit
将需要进行测试Bean直接在测试类中进行注入。
5.3.1 导入Spring集成Junit的坐标
<!-- spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
<scope>test</scope>
</dependency>
5.3.2 使用@Runwirh注解替换原来的运行期
5.3.3 使用@ContextConfiguration指定配置文件或配置类
5.3.4 使用@Autowired注入需要测试的对象
5.3.5 创建测试方法进行测试
- 2-5步骤都在一个文件中
package com.laity.test;
import com.laity.config.SpringConfiguration;
import com.laity.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author: Laity
* @Project: JavaLaity
* @Package: com.laity.test.SpringJunitTest
* @Date: 2022年05月26日 22:50
* @Description: SpringJunitTest
*/
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration("classpath:applicationContext.xml")
@ContextConfiguration(classes = SpringConfiguration.class)
public class SpringJunitTest
@Autowired
private UserService userService;
@Test
public void test()
userService.save();
七、Spring AOP
7.1 什么是AOP
AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程,是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
AOP 是 OOP(面向对象编程) 的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
7.2 AOP的作用及其优势
作用:在程序运行期间,在不修改源码的情况下对方法进行功能增强
优势:减少重复代码,提高开发效率,并且便于维护
面向切面编程 – 目标方法+增强方法 – 解耦合 – 运行时增强功能。
7.3 AOP的底层实现
实际上,AOP 的底层是通过 Spring 提供的的动态代理技术实现的。在运行期间,Spring通过
以上是关于一文入门Spring的主要内容,如果未能解决你的问题,请参考以下文章
❤️爆肝万字!一文最全总结之Spring从入门到入土❤️(建议收藏)