1、简介
1.1、介绍
Spring : 春天 —>给软件行业带来了春天
Spring是一个基于java的轻量级的、一站式框架,贯穿于表现层、业务层、持久层。
虽然Spring是一个轻量级框架,但并不表示它的功能少。实际上,spring是一个庞然大物,包罗万象。 时至今日,Spring已经成为java世界中事实上的标准。
Spring之父:Rod Johnson(罗德.约翰逊) 他是悉尼大学音乐学博士,而计算机仅仅是学士学位。 由于Rod对JAVAEE笨重、臃肿的现状深恶痛绝,以至于他将他在JAVAEE实战中的经历称为噩梦般的经历。他决定改变这种现状,于是就有了Spring。
1.2、优点
1.低侵入式设计
2.独立于各种应用服务器
3.依赖注入特性将组件关系透明化,降低耦合度
4.面向切面编程特性允许将通用任务进行集中式处理
5.与第三方框架的良好整合
简单的说就是灵活集成、降低耦合、简化开发。
1.3、spring的架构体系
1.Data Access/Integration(数据访问/集成)
-
JDBC:提供了JDBC的抽象层,减少在开发过程中对数据库操作时的编码;
-
ORM:对象关系映射,对流行的对象关系映射API;
-
OXM:提供了一个支持对象/XML映射的抽象层实现;
-
JMS:Java消息传递服务,包含使用和产生信息的特性;
-
Transactions事务:支持对实现特殊接口以及所有POJO类的编程和声明式事务处理;
2.Web
1.WebSocket:提供了WebSocket和SockJS的实现以及STOMP的支持;
2.Servlet:也称为Spring-webmvc模块,包含了Spring的模型-视图-控制器(MVC)和REST WebServices实现的Web应用程序;
3.Web:提供了基本的Web开发集成特性,如:多文件上传功能、使用Servlet监听器来初始化IOC容器以及Web应用上下文。
4.Portlet:提供了在Portlet环境中使用MVC实现,类似Servlet的功能;
3.Core Container(核心容器)
1.Beans模块:提供BeanFactory,对Java Bean进行管理,Spring将管理对象称为Bean;
JavaBean实际就是一个普通的Java类,为了规范开发,JavaBean具有如下特点:
① 具有一个公共的、无参的构造方法;
② 对应的属性必须提供了setter和getter方法用于外部属性赋值和获取属性值;
2.Core模块:提供了Spring框架的基本组成部分,包括IOC(控制反转)和DI(依赖注入)功能;
3.Context上下文模块:建立在Core和Beans的基础上,它是访问定义和配置的任何对象的媒介,提供了邮件服务、任务调度、远程访问、缓存、JNDI等支持。其中ApplicationContext接口是上下文模块的焦点;
4.SpEL模块:提供了强大的表达式语言去支持运行时查询和操作对象图;
4.其他模块
1.AOP模块:提供了面向切面编程实现,允许定义方法拦截器和切入点,将代码按照功能进行分离,以降低耦合性;
2.Aspects模块:提供了与AspectJ的集成功能,AspectJ是一个功能强大切成熟的面向切面编程框架;
3.Instrumentation模块:提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用;
4.Messaging模块:提供了对消息传递体系结构和协议的支持;
5.Test模块:提供了对单元测试和集成测试的支持;
2、步骤
1. 下载依赖jar包,并引入到项目中
2.编写Spring配置文件
3.编写测试代码通过Spring进行属性注入
这里我就直接将我用的spring的maven依赖放到下面了
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cskt</groupId>
<artifactId>springday</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
<scope>provided</scope>
</dependency>
<!-- 1.Spring核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- 2.Spring dao依赖-->
<!-- spring-jdbc包括了一些如jdbcTemplate的工具类-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- 3.Spring web依赖 -->
<!-- 4.Spring test依赖:方便做单元测试和集成测试 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.0</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
</project>
3、Spring两大核心技术(IOC/DI + AOP)
控制反转(IoC:Inversion of Control)/依赖注入(DI:Dependency Injection)
控制反转(loC)
控制反转是一种思想。
控制反转是为了降低程序耦合度,提高程序扩展力。
控制反转,反转的是什么?
将对象的创建权利交出去,交给第三方容器负责。
将对象和对象之间关系的维护权交出去,交给第三方容器负责。
依赖注入(DI)
Dl (Dependency Injection) :依赖注入,依赖注入实现了控制反转的思想。
依赖注入:
指Spring创建对象的过程中,将对象依赖属性通过配置进行注入依赖注入常见的实现方式包括两种:
第一种: set注入
第二种:构造注入工
所以结论是:IOC就是一种控制反转的思想,而DI是对loC的一种具体实现。
1.setter方式注入
创建一个用户的domain(实体类) !!!必须生成set方法,才能完成setter方式的注入
package com.cskt.doMain;
import lombok.Data;
import java.io.Serializable;
/**
* @BelongsProject: springday
* @BelongsPackage: com.cskt.doMain
* @Author: Th
* @CreateTime: 2023-08-14 18:49 周一
* @Description: TODO
* @Version: 1.0
*/
@Data
public class User implements Serializable {
private String id;
private String name;
private String password;
}
在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:context="http://www.springframework.org/schema/context"
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/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--反射模式 通过全路径名 能够拿到类里面的所有属性 class具体-->
<bean id="user" class="com.cskt.doMain.User">
<property name="id" value="1"/>
<property name="name" value="张三"/>
</bean>
2. 构造注入
给学生类写个带参的构造函数(写完带参的构造函数后,必须再定义一个无参的构造函数)
//构造注入
public class Student {
public Student(){
}
public Student(int num,String name){
}
//学号
private int num;
//姓名
private String name;
}
在applicationContext.xml文件中赋值
<!-- 构造器注入 -->
<bean id="st" class="Student">
<constructor-arg>
<value type="java.lang.int">101</value>
</constructor-arg>
<constructor-arg>
<value type="java.lang.String">张三</value>
</constructor-arg>
</bean>
2.面向切面编程(Aspect-Oriented Programming,AOP)
面向切面编程,简单地说就是在不改变原程序的基础上为代码段增加新功能,对代码段进行增强处理
前置增强、后置增强、最终增强、异常增强、环绕增强(定义一个用于增强的FirstAop类)
AOP相关术语
Aspect(切面), Advice(增强处理), Pointcut(切入点)
Join Point(连接点), Target Object(目标对象) ,AOP proxy(AOP 代理)
Weaving(织入)
传统方式的配置文件太复杂了,就直接使用注解了
aspect包下的MyAspect文件
package com.cskt.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
/**
* @BelongsProject: springday
* @BelongsPackage: com.cskt.aspect
* @Author: Th
* @CreateTime: 2023-08-15 09:26 周二
* @Description: TODO
* @Version: 1.0
*/
@Aspect
public class MyAspect {
//匹配com.cskt.service包及其子包下所有类的所有方法
// @Before("*.com.cskt.service..*.*(..)")
@Before("execution(* com.cskt.service..*.*(..)))")
public void before() {
System.out.println("前置通知.... 在方法之前要執行的公共代码放在这里");
}
/**
* 后置通知
* returnVal,切点方法执行后的返回值
*/
@AfterReturning(value = "execution(* com.cskt.service..*.*(..)))", returning = "returnVal")
public void AfterReturning(Object returnVal) {
System.out.println("后置通知...." + returnVal);
}
/**
* 环绕通知
*
* @param joinPoint 可用于执行切点的类
* 具体什么业务
* @return
* @throws Throwable
*/
@Around("execution(* com.cskt.service..*.*(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕通知前....");
Object obj = (Object) joinPoint.proceed();
System.out.println("环绕通知后....");
return obj;
}
/**
* 抛出通知
*
* @param e
*/
@AfterThrowing(value = "execution(* com.cskt.service..*.*(..))", throwing = "e")
public void afterThrowable(Throwable e) {
System.out.println("出现异常:msg=" + e.getMessage());
}
/**
* 无论什么情况下都会执行的方法
*/
@After(value = "execution(* com.cskt.service..*.*(..))")
public void after() {
//方法的对象的关闭
//方法的回滚
System.out.println("最终通知....");
}
}
mapper和实现类
package com.cskt.mapper;
/**
* @BelongsProject: springday
* @BelongsPackage: com.cskt
* @Author: Th
* @CreateTime: 2023-08-14 19:00 周一
* @Description: TODO
* @Version: 1.0
*/
public interface SmsUserMapper {
/**
* 新增注入
* @return
*/
int insert();
}
package com.cskt.mapper;
/**
* @BelongsProject: springday
* @BelongsPackage: com.cskt.mapper
* @Author: Th
* @CreateTime: 2023-08-14 19:41 周一
* @Description: TODO
* @Version: 1.0
*/
public class SmsUserMapperImpl implements SmsUserMapper{
@Override
public int insert() {
System.out.println("执行了新增方法。。。。。。。。");
return 0;
}
}
以及service层和实现类
package com.cskt.service;
public interface UserService {
int addUser();
}
package com.cskt.service;
import com.cskt.mapper.SmsUserMapper;
import com.cskt.mapper.SmsUserMapperImpl;
/**
* @BelongsProject: springday
* @BelongsPackage: com.cskt.service
* @Author: Th
* @CreateTime: 2023-08-14 19:41 周一
* @Description: TODO
* @Version: 1.0
*/
public class UserServiceImpl implements UserService{
/**
* 重复的new 对象 构造注入 就是解决 service 和dao 的问题
*/
public SmsUserMapperImpl userMapper;
public UserServiceImpl(SmsUserMapperImpl userMapper) {
this.userMapper = userMapper;
}
@Override
public int addUser() {
userMapper.insert();
return 0;
}
}
测试类
@Test
public void testService() {
//第一步:读取Spring的核心文件
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//第二步:根据ac对象获得里面所有的bean
UserService userService = (UserService) context.getBean("userService");
//第三步:调用方法
userService.addUser();
}
总结: