博主主页: 码农派大星.
** 数据结构专栏**:Java数据结构
** 数据库专栏:**MySQL数据库
**JavaEE专栏:**JavaEE
关注博主带你了解更多数据结构知识
1. 应用分层
应⽤分层是⼀种软件开发设计思想,它将应⽤程序分成N个层次,这N个层次分别负责各⾃的职责,多个层次之间协同提供完整的功能.根据项⽬的复杂度,把项⽬分成三层,四层或者更多层,之前为了让项⽬快速上线,我们通常是不考虑分层的.但是随着业务越来越复杂,⼤量的 代码混在⼀起,会出现逻辑不清晰、各模块相互依赖、代码扩展性差、改动⼀处就牵⼀发⽽动全⾝等问题.所以学习对项⽬进⾏分层对我们来说就是很有必要的了.
1.1 如何分层:
我们上一篇博客中学的Spring MVC中就把整体的系统分成了Model(模型),View(视图)Controller(控制器)三个层次,也就是将⽤⼾视图和业务处理隔离开,并且通过控制器连接起来,很好地实现了表现和逻辑的解耦,是⼀种标准的软件分层架构
对于我们后端开发来说,我们可以把整体架构分为表现层、业务逻辑层和数据层.这种分层⽅式也称之为"三层架构"
表现层:就是展⽰数据结果和接受⽤⼾指令的,是最靠近⽤⼾的⼀层;(请求处理、响应数据:负责,接收⻚⾯的请求,给⻚⾯响应数据)
业务逻辑层:负责处理业务逻辑, ⾥⾯有复杂业务的具体实现;(逻辑处理:负责业务逻辑处理的代码)
数据层: 负责存储和管理与应⽤程序相关的数据(数据访问:负责业务数据的维护操作,包括增、删、改、查等操作.)
在Spring中我们把这三层分别分为:
Controller:控制层,接收前端发送的请求,对请求进⾏处理,并响应数据。
Service:业务逻辑层,处理具体的业务逻辑。
Dao:数据访问层,也称为持久层。负责数据访问操作,包括数据的增、删、改、查
1.2 MVC与三层架构区别联系
MVC 是一种设计模式,用于分离应用程序的用户界面(UI)和业务逻辑,强调用户界面和业务逻辑的分离,使得开发者可以专注于单一方面的开发,而不必担心其他部分的实现细节
三层架构是一种软件架构模式,强调应用程序的不同功能层之间的分离,使得每一层都可以独立开发和测试
MVC 更侧重于用户界面的实现和业务逻辑的分离,而三层架构侧重于整个应用程序的分层和模块化
MVC模式强调数据和视图分离,将数据展⽰和数据处理分开,通过控制器对两者进⾏组合. 三层架构强调不同维度数据处理的⾼内聚和低耦合,将交互界⾯,业务处理和数据库操作的逻辑分开
联系:提高代码的可维护性和可扩展性,⼆者的⽬的是相同的,都是"解耦,分层,代码复⽤"
可测试性:通过分离不同的功能到不同的层或组件,两者都使得单元测试和集成测试变得更加容易。
可维护性:在 MVC 和三层架构中,代码的组织方式使得维护和更新变得更加简单
2. Spring
Spring就是包含了众多⼯具⽅法的IoC容器
3.IoC & DI⼊⻔
**3.1 **什么是IoC?
IoC 是Spring的核⼼思想,其实IoC我们在前⾯已经使⽤了,我们在前⾯讲到,在类上⾯添加 @RestController 和 @Controller 注解,就是把这个对象交给Spring管理,Spring框架启动时就会加载该类.把对象交 给Spring管理,就是IoC思想.
IoC: Inversion of Control (控制反转),也就是说Spring是⼀个"控制反转"的容器
什么是控制反转呢? 也就是控制权反转.什么的控制权发⽣了反转? 获得依赖对象的过程被反转了 也就是说,当需要某个对象时,传统开发模式中需要⾃⼰通过new创建对象,现在不需要再进⾏创 建, 把创建对象的任务交给容器, 程序中只需要依赖注⼊(DI)就可以了. 这个容器称为:IoC容器. Spring是⼀个IoC容器,所以有时Spring也称为Spring容器
控制反转是⼀种思想,在⽣活中也是处处体现. ⽐如⾃动驾驶, 传统驾驶⽅式,⻋辆的控制权由驾驶员行驶来控制,现在交给了驾驶自动化系统来控制,这也是控制反转思想在⽣活中的实现
IoC容器具备优点:
资源集中管理: IoC容器会帮我们管理⼀些资源(对象等),我们需要使⽤时,只需要从IoC容器中去取 就可以了
我们在创建实例的时候不需要了解其中的细节,降低了使⽤资源双⽅的依赖程度,也就是耦合度
3.2 DI 介绍
DI就是依赖注入
它是实现 IoC一种设计模式。依赖注入的主要思想是将组件的依赖关系(即它所依赖的对象或资源)通过外部传递给它,而不是让组件自己创建或查找这些依赖
DI 是 IoC 的一种实现方式,它专注于解决对象之间的依赖关系。在 DI 中,一个对象(称为消费者)所依赖的另一个对象(称为服务提供者)不是由消费者自己创建的,而是由 IoC 容器在运行时动态注入到消费者中
4.IoC 使⽤
类注解:@Controller、@Service、@Repository、@Component、@Configuration.
⽅法注解:@Bean
4.1 类注解区别
@Controller:控制层,接收请求,对请求进⾏处理,并进⾏响应.
@Servie:业务逻辑层,处理具体的业务逻辑.
@Repository:数据访问层,也称为持久层.负责数据访问操作
@Configuration:配置层.处理项⽬中的⼀些配置信息
我们发现@Service、@Repository、@Configuration.中都包含@Component说明这些注解本身属于@Component的“子类”。
4.2 ⽅法注解@Bean
1.使⽤外部包⾥的类, 没办法添加类注解
- ⼀个类,需要多个对象,⽐如多个数据源
4.2.1⽅法注解要配合类注解使⽤
@Component
public class UserInfoComonent {
@Bean
public UserInfo userInfo(){
return new UserInfo("zhangsan",29);
}
}
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(DemoApplication.class, args);
UserInfo bean = context.getBean(UserInfo.class);
System.out.println(bean);
}
4.2.2 定义多个对象
定义多个对象运行会报错,对象不唯一,运行失败
@Component
public class UserInfoComonent {
@Bean
public UserInfo userInfo(){
return new UserInfo("zhangsan",29);
}
@Bean
public UserInfo userInfo1(){
return new UserInfo("lisi",23);
}
}
可以看出来, @Bean注解的bean,bean的名称就是它的⽅法名
**@Bean可以针对同⼀个类,定义多个对象,但我们得根据他们的名称来获取bean对象 **
Object userInfo1 = context.getBean("userInfo1");
System.out.println(userInfo1);
4.2.3 重命名Bean
可以通过设置name属性给Bean对象进⾏重命名操作,name={} 可以省略,也可以重命名多个名字
public class UserInfoComonent {
@Bean(name = {"cxk","zhangsan"})
public UserInfo userInfo(){
return new UserInfo("zhangsan",29);
}
@Bean(name = "mjq")
public UserInfo userInfo1(){
return new UserInfo("lisi",23);
}
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Object userInfo1 = context.getBean("cxk");
System.out.println(userInfo1);
}
5. DI 依赖注入
依赖注⼊,Spring给我们提供了三种⽅式:
1. 属性注⼊
2. 构造⽅法注⼊
3. Setter 注⼊
**5.1 **属性注⼊
属性注⼊是使⽤ @Autowired 实现的,将Service类注⼊到Controller类中
@Service
public class UserService {
public void say(){
System.out.println("UserService say....");
}
}
@Controller
public class UserCotroller {
@Autowired
private UserService userService;
public void say(){
System.out.println("UserController say....");
userService.say();
}
}
UserCotroller bean = context.getBean(UserCotroller.class);
bean.say();
5.2 构造方法注入
构造⽅法注⼊是在类的构造⽅法中实现注⼊,如果类只有⼀个构造⽅法,那么@Autowired 注解可以省略
@Controller
public class UserCotroller {
private UserService userService;
public UserCotroller(UserService userService) {
this.userService = userService;
}
public void say(){
System.out.println("UserController say....");
userService.say();
}
}
如果存在多种构造方法需要添加上@Autowired 来明确指定到底使⽤哪个构造⽅法
@Controller
public class UserCotroller {
private UserService userService;
public UserCotroller() {
System.out.println("无参构造");
}
@Autowired
public UserCotroller(UserService userService) {
this.userService = userService;
System.out.println("有参构造");
}
public void say(){
System.out.println("UserController say....");
userService.say();
}
}
5.3 Setter 注⼊
Setter 注⼊和属性的Setter⽅法实现类似,只不过在设置set⽅法的时候需要加上@Autowired 注解
@Controller
public class UserCotroller {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
public void say(){
System.out.println("UserController say....");
userService.say();
}
}
5.4 三种注⼊优缺点
属性注⼊
优点:简洁,使⽤⽅便
缺点:只能⽤于IoC容器,如果是⾮IoC容器不可⽤,并且只有在使⽤的时候才会出现NPE(空指 针异常)
不能注⼊⼀个Final修饰的属性
构造函数注⼊
优点:
可以注⼊final修饰的属性
注⼊的对象不会被修改
依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造⽅法中执⾏的,⽽构造⽅法 是在类加载阶段就会执⾏的⽅法.
通⽤性好,构造⽅法是JDK⽀持的,所以更换任何框架,他都是适⽤的
缺点:
注⼊多个对象时,代码会⽐较繁琐
Setter注⼊
优点: ⽅便在类实例之后,重新对该对象进⾏配置或者注⼊
缺点:
不能注⼊⼀个Final修饰的属性
注⼊对象可能会被改变,因为setter⽅法可能会被多次调⽤,就有被修改的风险
5.5 @Autowired存在问题
@Component
public class UserInfoComonent {
@Bean
public UserInfo userInfo(){
return new UserInfo("zhangsan",29);
}
@Bean
public UserInfo userInfo1(){
return new UserInfo("lisi",23);
}
}
当同⼀类型存在多个对象时,按照名称来匹配,该类型只有一个对象时,直接注入;有多个对象时,按照名称注入
@Primary
当存在多个相同类型的Bean注⼊时,加上@Primary注解,确定哪个是默认的实现
@Component
public class UserInfoComonent {
@Bean
public UserInfo userInfo(){
return new UserInfo("zhangsan",29);
}
@Primary
@Bean
public UserInfo userInfo1(){
return new UserInfo("lisi",23);
}
@Bean
public UserInfo userInfo2() { return new UserInfo("cxk",34);}
}
@Qualifier
使⽤@Qualifier注解:指定当前要注⼊的bean对象。在@Qualifier的value属性中,指定注⼊的bean 的名称
@Qualifier注解不能单独使⽤,必须配合@Autowired使⽤
@Component
public class UserComponent {
@Qualifier("userInfo2")
@Autowired
private UserInfo ui;
public void say(){
System.out.println("UserComponent say.... ");
System.out.println(ui);
}
}
@Component
public class UserInfoComonent {
@Bean
public UserInfo userInfo(){
return new UserInfo("zhangsan",29);
}
@Bean
public UserInfo userInfo1(){
return new UserInfo("lisi",23);
}
@Bean
public UserInfo userInfo2() { return new UserInfo("cxk",34);}
}
@Component
public class UserInfoComonent {
@Bean
public UserInfo userInfo(){
return new UserInfo("zhangsan",29);
}
@Bean
public UserInfo userInfo1(){
return new UserInfo("lisi",23);
}
@Bean
public String name(){
return "cxk";
}
@Bean
public String name1(){
return "mjq";
}
@Bean
public UserInfo userInfo2(@Qualifier("name") String name3) { return new UserInfo(name3,34);}
}
@Resource
@Resource注解:是按照bean的名称进⾏注⼊。通过name属性指定要注⼊的bean的名称
@Component
public class UserInfoComonent {
@Bean
public UserInfo userInfo(){
return new UserInfo("zhangsan",29);
}
@Bean
public UserInfo userInfo1(){
return new UserInfo("lisi",23);
}
}
@Component
public class UserComponent {
@Resource(name = "userInfo1")
private UserInfo ui;
public void say(){
System.out.println("UserComponent say.... ");
System.out.println(ui);
}
}
@Resource 和@Autowired区别
@Autowired是spring框架提供的注解,⽽@Resource是JDK提供的注解
@Autowired默认是按照类型注⼊,⽽@Resource是按照名称注⼊.相⽐于@Autowired 来说, @Resource ⽀持更多的参数设置,例如name设置,根据名称获取Bean.
@Autowired根据类型匹配,@Resource根据名称匹配,优先按照类型匹配,如果同类型右多个对象,再按照名称匹配,它两基本原则都是根据类型匹配,但是@Autowired不能指定名称
6.Spring, Spring Boot和SpringMVC的关系以及区别
Spring: 简单来说,Spring是⼀个开发应⽤框架,什么样的框架呢,它轻量级、⼀ 站式、模块化,其⽬的是⽤于简化企业级应⽤程序开发,Spring的主要功能:管理对象,以及对象之间的依赖关系,⾯向切⾯编程,数据库事务管理,数据访 问,web框架⽀持等,但是Spring具备⾼度可开放性,并不强制依赖Spring,开发者可以⾃由选择Spring的部分或者全 部,Spring可以⽆缝继承第三⽅框架,⽐如MyBaties
Spring MVC:SpringMVC是Spring的⼀个⼦框架,Spring诞⽣之后,⼤家觉得很好⽤,于是按照MVC 模式设计了⼀个MVC框架(⼀些⽤Spring解耦的组件),主要⽤于开发WEB应⽤和⽹络接⼝,所以, Spring MVC是⼀个Web框架.Spring MVC基于Spring进⾏开发的,天⽣的与Spring框架集成.可以让我们更简洁的进⾏Web层 开发,⽀持灵活的URL到⻚⾯控制器的映射,提供了强⼤的约定⼤于配置的契约式编程⽀持,⾮常 容易与其他视图框架集成
Spring Boot: Spring Boot是对Spring的⼀个封装,为了简化Spring应⽤的开发⽽出现的,使⽤SpringBoot可以更加快速的搭建框架,降级开发成本,让开发 ⼈员更加专注于Spring应⽤的开发,⽽⽆需过多关注XML的配置和⼀些底层的实现
SpringMVC和SpringBoot都属于Spring,SpringMVC是基于Spring的⼀个 MVC框架,⽽SpringBoot是基于Spring的⼀套快速开发整合包
版权归原作者 码农派大星. 所有, 如有侵权,请联系我们删除。