—— Feellmoose

视频链接: https://njupt-sast.feishu.cn/minutes/obcn4w8r4q1h8u5dn6fvj9cq?from=from_copylink

Spring是一个非常成熟的全栈框架。但是互联网发展的迅猛代表技术的更迭是非常迅速的,大家学习要注意领会思想,同时在使用时要注意时效性和不同版本带来的问题,养成搜索和阅读源码的好习惯。

Spring主要解决的问题:

1.解耦与简化开发(Ioc控制反转)

通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。有了Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

2.AOP编程的支持

通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。

3.声明事务的支持

在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。

4.方便程序的测试

可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情。Spring对Junit4支持,可以通过注解方便的测试Spring程序。

5.方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度。Spring自身就是一个用来集成各种框架的框架。

6.降低Java EE API的使用难度

Spring对很多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。

7.Java 源码是经典学习范例

Spring的源码设计精妙、结构清晰、匠心独用,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。Spring框架源码无疑是Java技术的最佳实践范例。如果想在短时间内迅速提高自己的Java技术水平和应用开发水平,学习和研究Spring源码将会使你收到意想不到的效果。


核心原理:

一.Spring核心提供容器(container):spring应用上下文

用来创建和管理应用组件(bean),实现了控制反转(Ioc)

二.将bean装配在一起:基于依赖注入(DI)

1.通过xml文件;(但是现在我们使用Springboot,虽然在启动时有性能的损耗,但是使用注解来注册组件是现在的主流方式,扫描和自动装配更加方便,编写也更加容易,代码读写更加容易)

2.通过注释配置类@configration其中的@bean可以将其他框架组件或者是自定义组件以spring对象的形式加载到容器中,例如拦截器配置类(注册拦截器):

这里我们需要注意普通对象和spring对象的区别:

普通对象是由我们自己创建的不存在spring上下文中,不能享受容器带来的各种服务,不能和容器中各种对象进行直接交互。

spring对象是由spring工厂类帮我们创建的对象,可以享受到容器带来的便捷服务,可以直接和容器中的对象进行交互。

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 配置拦截器
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Autowired
private TokenInterceptor tokenInterceptor;

@Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(tokenInterceptor).addPathPatterns("/**");
}
}

(注意在某些IDE中推荐使用@Resouce作为对象注入的注解,作用非常类似,不过@Autowird注解默认通过byType方式注入,而@Resource注解默认通过byName方式注入)

3.通过自动装配@autowire和组价扫描@component识别到应用上下文中;

4.springboot自动配置,下面我们拿使用最频繁的springweb举例

1
2
3
4
5
6
7
8
9
10
11
12
// 以下为Lombok注解,不需要我们写构造器和 Getter Setter 方法
// 博客内有其他文章详细介绍,这是springboot框架以外的注解。
@Data
@AllArgsConstructor
@NoArgsConstructor
//以上为Lombok注解
public class User {
private Integer id;
private String userName;
private String password;
private String email;
}
1
2
3
4
5
6
@Mapper
@Repository
public interface UserMapper {
// 示例,可以去resources->mapper中查看UserMapper.xml文件的内容。
void addUser(@Param("user")User user);
}
1
2
3
4
5
6
7
@Service
public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
public UserServiceImpl(UserMapper userMapper) {
this.userMapper = userMapper;
}
}
1
2
3
4
5
6
7
8
9
@RestController
@RequestMapping("/user")
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}

以上也是常见的MVC架构,前后端分离,后端不再需要提供view部分,只提供controller层(API)来接受前端的请求,并返回view层需要的模型和数据给前端。

各层的功能分配:

controller层调用service层完成业务逻辑

service层调用mapper层完成数据交换

mapper层负责与数据库等其他中间件的连接和数据模型的传输

model是数据模型,比如订单,商品等实际意义的模型,或者是返回值类型等抽象模型。


SpringBoot项目组成:

在创建完Springboot项目之后,我们可以看到项目已经有了初始的结构,接下来让我们从项目结构入手,看一看spring框架。

引导类:(识别和应用的入口)

1
2
3
4
5
6
7
8
9
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

@springbootapplication(表明是一个springboot应用,组合注解 1.声明其为配置类,在引用启动时自动加载到容器中 2.启动自动配置 3.启动组件扫描,可以通过 @component @controller @service 等注解声明其他类为组件并自动加载到容器中)

运行springapplication的run方法执行应用上下文

测试类:(用来测试方法)

一个完整的项目需要保证项目测试的稳定和上线的稳定性,我们既需要刚刚完成的项目模块可以正常运行,又需要保证对其他模块没有干扰,这样项目中的单元测试显得尤为重要。在完整的大型需要项目中,为了长期维护和更新,单元测试是必须完成的。

1
2
3
4
5
6
7
8
9
10
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemoApplicationTests {
@Test
void contextLoads() {
//单元测试写在这里
}
}

@runwith(springrunner.class) 提供一个测试运行器runner用来指导junit如何运行

@springtest + 类

@test + 方法

resource

文档静态资源与配置文件的存放

application.properties

配置文件