• Spring MVC和Spring Boot


    上节已经提到过请求,这次梳理响应。

    响应

    响应基本上都要被@Controller所托管,告诉Spring帮我们管理这个代码,我们在后面需要访问时,才可以进行访问,否则将会报错。并且其是由@RestController分离出来的,@RestController分离出来了@Controller来返回视图,随着现在前后端的彻底分离,现在返回视图所需要的数据,还分离出@RestponseBody来进行返回数据。

    1.返回静态页面

    @Controller进行对其的托管,并且这个注解只能修饰类,Spring 容器会将其实例化并管理起来,使得它可以接收并处理客户端的请求,并且一般负责负责接收和处理 HTTP 请求,调用业务逻辑完成业务处理,生成视图并返回给客户端,处理异常情况等。

    切记在return的后面加上/来确保其是以url的格式 进行返回

    1. @Controller
    2. public class text {
    3. @RequestMapping("index")
    4. public String teturnIndex(){
    5. return "/index.html";
    6. }
    7. }

    在响应不加@Controller进行托管,直接就会报错

    2.返回数据

    @RestsponseBody注解来进行修饰,可以修饰类和方法,修饰类时表示这个类下的所有方法返回的都是数据,修饰方法时,表示该方法返回的是数据。所以如果一个类的所有方法都是返回数据直接加到类上,避免重复性操作。

    1. @ResponseBody
    2. @RequestMapping("/returnData")
    3. public String returnData(){
    4. return "返回数据";
    5. }

    3.返回html的代码片段

    @RestsponseBody注解来进行修饰

    1. @ResponseBody
    2. @RequestMapping("/returnHtml")
    3. public String returnHtml(){
    4. return "\"button\" value=\"提交\" id=\"checkCaptcha\">";
    5. }

    4.返回JSON

    当我们的接口返回的是String时, content-Type是text/html
     

    1. @ResponseBody
    2. @RequestMapping("/returnHtml2")
    3. public String returnHtml2(){
    4. String name = "zhangsan";
    5. return name;
    6. }

    当我们的接口返回的是对象时, content-type自动设置为application/json Map

    1. @ResponseBody
    2. @RequestMapping("/returnJson")
    3. public Person returnJson(){
    4. Person person = new Person();
    5. person.setAge(12);
    6. person.setName("zhangsan");
    7. return person;
    8. }

    5.返回设置状态码

    1. @ResponseBody
    2. @RequestMapping("/setStatus")
    3. public String setStatus(HttpServletResponse response){
    4. response.setStatus(404);
    5. return "设置状态码";
    6. }

    6.设置Header 

    默认是返回html,可以改成json。但是还需要匹配,不匹配仍然报错。

     consume:限制响应的提交内容类型(Content-Type),例如applicationljson, text/html;,如果指定application/sor
    produces:设置返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
    (???)在哪里用到了

    1. @ResponseBody
    2. //@RequestMapping(value = "r1")不设置返回类型默认html
    3. @RequestMapping(value = "/r1",produces = "application/json; charset=utf-8")//设置返回类型Json,但仍然需要匹配
    4. public String r1(HttpServletResponse response){
    5. return "{'ok':1}";
    6. }

    三层架构

    三层架构主要将程序代码分为三个部分来进行分别书写,减少代码的耦合性,将应用程序分为表示层、业务逻辑层和数据访问层,每一层都有明确定义的责任,彼此不互相干扰。

    1.表现层:接收请求,返回结果业务
    2.业务逻辑层:主要处理业务逻辑

    3.数据层:处理数据,包含数据的存储,获取(增删改查)

    在代码中一般将其三层放在这三个对应的包内

    Controller:接收请求,参数是否合法,结果响应

    Service:处理请求(主要干活的部分)
    Dao:数据部分(将数据从数据库中取处理让Service进行处理)

    MVC注重数据和视图的分离。

    三层架构注重从不同方向上取处理。

    两者都是为了更好书写的代码,将代码通过自己的思想将不同的部分进行分离出来,使最终写成的程序可以有更好的可维护性,扩展性等。二者在进行一个系统设计时可以分别使用,也可以一起使用。

    例如一起使用时,可以将MVC中的视图作为表示层的实现,将控制器作为业务逻辑层的门面,将模型作为业务逻辑层的实现。这样做的好处是可以更加紧密地结合业务逻辑和用户界面,提高系统的开发效率和可维护性。

    例如分别使用时,可以首先设计并实现三层架构,将系统分为表示层、业务逻辑层和数据访问层,然后在每一层中使用MVC进行设计和实现。这样做的好处是可以更加清晰地分离不同层次的责任,使系统的架构更加模块化和灵活。

    注:

    命名建议
    大驼峰: BookDao
    类名使用大驼峰
    小驼峰: bookDao
    变量名小驼峰
    蛇形: book_dao
    数据库,字段命名用蛇形
    串形: book-dao

     

    Spring的核心思想之一IOC
     

    Spring是一个包含众多工具的loC容器
    容器就是用来存储各种数据的东西。

    list/map装各种数据类型的容器
    tomcat装web的容器
    Spring容器,装的是对象

    Spring容器中存的是对象,对象这个词,在Spring的范围内,称之为bean

    loC:控制反转(控制权反转)就是创建对象的控制权,交给了Spring。

    例如下面代码中,如果想要让这个车能正常行驶起来行驶,并且想要生产不同的车轮大小,需要将在最开始就将车轮胎的代码传输过去,其耦合性极高,中间一个代码出现问题,全寄。

    1. class Car {
    2. private Framework framework;
    3. public Car(int size) {
    4. framework = new Framework(size);
    5. System.out.println( "car init. .. ");
    6. }
    7. public void run() {
    8. System.out.println( "car run. . . ");
    9. }
    10. }
    11. class Framework {
    12. private Bottom bottom;
    13. public Framework(int size) {
    14. bottom = new Bottom(size);
    15. System.out.println( "framework init. . .." );
    16. }
    17. }
    18. class Bottom {
    19. private Tire tire;
    20. public Bottom(int size) {
    21. tire = new Tire(size);
    22. System.out.println("bottom init.. ." );
    23. }
    24. }
    25. class Tire {
    26. private int size;
    27. public Tire(int size) {
    28. this.size = size;
    29. System.out.println("tire init. . .size : "+size);
    30. }
    31. }

    所以这样进行设计就可以将生产汽车的各个组件隔离开来,哪里发生问题即刻就可以知道。减少了其耦合。一个寄不会全寄。

    1. class Car {
    2. private Framework framework;
    3. public Car() {
    4. framework = new Framework();
    5. System.out.println( "car init. . . " );
    6. }
    7. public void run() {
    8. System.out.println( "car run. . ." );
    9. }
    10. }
    11. class Framework {
    12. private Bottom bottom;
    13. public Framework(){
    14. bottom = new Bottom();
    15. System.out.println( "framework init. . .. " );
    16. }
    17. }
    18. class Bottom {
    19. private Tire tire;
    20. public Bottom() {
    21. tire = new Tire();
    22. System.out.println( "bottom init. .. " );
    23. }
    24. }
    25. class Tire {
    26. private int size = 21;
    27. public Tire() {
    28. System.out.println( "tire init. . ."+size );
    29. }
    30. }


    Spring帮我们管理对象
    1.告诉Spring,帮我们管理哪些对象 (存)
    2.知道如何取出来这些对象(取)

    Spring的loC思想实现了这种事情,通过DI最终来进行了实现。

    DI把依赖对象取出来,并在DI实现的这个类中直接赋给该对象的属性

    下面代码就进行了实现,可以看到要在一个类中使用另外一个类时,使用@Autowired这样的注解就不用在重复性的在这个类中去创建对象了。直接去使用。

    1. @Component
    2. @Data//可以不写setter和getter等创建类时的重复性操作
    3. class Student {//存到Spring中
    4. private String name;
    5. private Integer age;
    6. // 添加构造函数和 getter、setter 方法
    7. }
    8. @Controller
    9. class StudentCard {
    10. @Autowired
    11. private Student student;//从Spring中去取,
    12. public void text() {
    13. // 可以在这里使用注入的 student 对象
    14. System.out.println("Student name: " + student.getName());
    15. System.out.println("Student age: " + student.getAge());
    16. }
    17. }

    DI的具体实现依靠于两大注解类型

    存注解:

    类注解@Controller、@Service、@Repository、@Component、@Configuration.

    方法注解@Bean

    取注解:@Autowired@Resource@Qualifier@Inject@value 

    取注解一般使用@Autowired

    Spring上下文

    Spring上下文和DI的实现是紧密相关的,Spring上下文作为DI的实现载体,负责管理Bean之间的依赖关系,从而实现了IoC容器的功能。具体来说Spring上下文负责创建、管理和组织应用程序中的Bean,它会根据Bean之间的依赖关系,在需要的时候将依赖注入到相应的对象中。通过DI机制,Spring上下文实现了控制反转,将对象的创建和管理交给了Spring容器。

    @controller注解的作用

    从context中获取类的对象,@controller将类存入Spring之后就被称为bean对象。

    通过getBean来获取我们的类的对象。,并且通过这个对象去访问类中的方法。

    1. ApplicationContext context = SpringApplication.run(Demo9Application.class,args);
    2. Student bean = context.getBean(Student.class);
    3. bean.student();

    但是如果Student类中如果没有@Controller则是不能取到对象的,错误如下

    1. Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.demo9.Student' available
    2. at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
    3. at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
    4. at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1178)
    5. at com.example.demo9.Demo9Application.main(Demo9Application.java:13)

    @severive也和上面一样,这些存注解,都会将其存入到Spring中,想去取得时候就可以通过getBean来获取我们的类的对象。

    @Controller、@Service、@Repository、@Component、@Configuration,这些注解都是component的衍生类或者是他的本身所建立出来的。

    但是@Controller是被赋予了一些其他注解没有的功能,其在Spring MVC中具有特殊的作用,它用于标记一个类作为控制器(Controller),用于处理HTTP请求。

    以及必需使用@Controller代码的入口才能正常加载,否则会报如下错误

    并且上述五大注解只能放类上,只能加在我们自己写的代码上。如果我引入了一个第三方Jar包,也希望交给Spring管理,是没有办法加五大注解。

    这些都是针对于一个对象来进行管理,但是如果对于一个类,定义多个对象时,比如数据库操作,定义多个数据源,就需要使用@Bean来进行操作了
    Bean是方法注解
    @Bean必须搭配五大注解来使用

    否则单独使用的话会报如下的错误,大致意思是程序没有找到bean对象。加上五大注解就意外着向Spring容器上传,接下来使用时,就会找到


     

    并且使用@bean注解时,bean的名称必需是类名,否则不能找到对应的bean对象。

    注:如果需要的Bean的类型,对应的对象只有一个时,就直接赋值如果有多个时,通过名称去匹配

    SpringBoot特点;约定大于配置其中之一体现:就是扫描路径

    其默认扫描路径是:启动类所在的目录及其子孙目录。但是我们可以通过这个注解可以指定扫描路径@ComponentScan( "com.bite.demo" ),如果没有指定那就是默认路径。

    DI的依赖注入

    依赖注入总共有三种

    1.属性注入2.构造方法注入3.Setter方法注入

    1. @Autowired
    2. private test test;//属性注入
    3. //Setter方法注入
    4. @Autowired
    5. private test test;
    6. @Autowired
    7. public getBean(test test){//构造
    8. this.test = test;
    9. }
    10. //构造方法注入
    11. private test test;
    12. @Autowired
    13. public getBean(test test){
    14. this.test = test;
    15. }

    都是将存入Spring容器中bean对象放到类中来进行使用。

    属性注入以类型进行匹配,与注入的属性名称无关但是如果一个类型存在多个对象时,优先名称匹配,如果名称匹配不上,寄报错。
    无法注入一个Final修饰的属性,想要注入1.定义时就进行赋值2.构造方法中进行赋值

    如果存在多个构造函数时,需要加@AutoWired注明使用哪个构造函数
    如果只有一个构造函数,@AutoWired可以省略掉

    属性注入:先将其里面的属性创建成功之后,其才能被创建好

    如果里面的属性是被static修饰的话,不用这样

    当程序中同一个类型有多个对象时,使用@AutoWired会报错(一些情况下)
    解决方法
    1.属性名和你需要使用的对象名保持一致

    2.使用@Qualifier

    1. @Controller
    2. class UserController4 {
    3. //注入
    4. @Resource(name = "user1" )
    5. private User user;
    6. public User getUser( ){
    7. return user;
    8. }
    9. }



    3使用@Resource注解

     

    1. @Controller
    2. public class UserController5 {
    3. //注入
    4. @Autowired
    5. @Qualifier(value = "user2")
    6. private User user;
    7. public User getUser() {
    8. return user;
    9. }
    10. }

    依赖注入的主要目的之一就是让类能够获取到由Spring容器管理的对象实例或其他依赖项,从而解耦组件之间的关系,不需要知道如何创建它所依赖的对象,只需定义它们所需的接口或抽象类型。

     

    @Autowird 与@Resource的区别
    @Autowired是spring框架提供的注解,而@Resource是JDK提供的注解
    @Autowired 默认是按照类型注入,而@Resource是按照名称注入.相比于@Autowired 来说,@Resource支持更多的参数设置,例如name 设置,根据名称获取 Bean。

    Bean的存
    使用五大注解和@Bean时, Spring会给一个默认的名称
    1.五大注解
    五大注解: BeanName是类名的小驼峰表示法(首字母小写)
    特殊情况:如果前两位字母都为大写,BeanName为类名

    如果在五大注解之中添加名称之后,就会更改五大注解bean的名称,Spring会使用程序员定义的Bean的名称。在启动类中获取对象时需要的就是BeanName。

    同理也可以修改@Bean的名称

    Bean的取

    1.属性注入@AutoWired
    ⒉.构造方法注入
    如果只有一个构造方法,@AutoWired可以省略
    3. Setter方法注入

    @AutoWired存在问题
    同一个类型的存在多个对象时,可能会出错解决思想:指定Bean的名称
    指定Bean
    1.修改@AutoWired修饰的属性名为需要的Bean的名称
    3.使用@Qualifity指定Bean的名称

    4.使用@Resource




     


     

  • 相关阅读:
    Springboot+JPA+Hibernate+GBase 8s示例
    【UnityShaderLab实现“Billboard“始终面向相机_播放序列图的效果_案例分享(内附源码)】
    Android Sutdio依赖Snapshot版本,无法同步最新的包
    2023年中国调音台产业链、产量及市场规模分析[图]
    [C#]vs2022安装后C#创建winform没有.net framework4.8
    基于vue实现滑块动画效果
    54、WEB攻防——通用漏洞&跨域CORS资源&JSONP回调&域名接管劫持
    工具MyBatis Generator(MBG)
    如何在STM32中实现TCP通信?
    电脑重装系统后如何在防火墙设置允许浏览器访问网络
  • 原文地址:https://blog.csdn.net/zhimeng3/article/details/137764763