2021-02-19

进程:一个程序,各种资源分配好放到内存中叫进程,进程是资源分配的基本单位

线程:程序开始之后之后,各种不同的执行路径,同时开始并行运行,是运行的基本单位;

线程切换/上下文切换:执行某个线程时,存储做计算的寄存器存放该线程的数据,pc记录执行到哪,然后切换另一个线程

 

Spring 解决的是业务层与各层之间的松耦合问题

控制反转 --帮助我们创建对象

依赖注入--给全局的属性或者对象进行赋值操作

面向切面--提升代码的扩展与功能

声明事务--事务管理

mybatis解决的层之间的松耦合的问题

 

为什么要引入接口,在软件设计中最难处理的就是需求的复杂变化,需求的复杂变化更对体现在具体的实现上,我们变成如果围绕具体实现来展开就会陷入更加复杂变化的汪洋中,软件也就不能最终实现。我们必修围绕某种稳定东西展开,以静制动,实现规范的高质量项目。接口就是规范,是项目中最为稳定的核心,面向接口编程而不是面向实现编程,可以大大降低程序模块之间的耦合性,提高整个系统的可扩展性和可维护性。另外,java是一种单继承多实现的语言,接口可以提供多继承的大多数好处,同时还能避免多继承的复杂行和低效性。

上图中接口规范了controller层中B类中的oo方法实现;但是却不能解决B类的更改问题,如果我们想在controller中不把B类改变为C类,但是controller层中可能有很多B类需要要更改,可见使用接口的方式仍然不能解决耦合问题,因此spring框架为我们提供了IOC容器的方式,因此我们用不自己创建对象,而是将创建对象的任务交给spring,spring通过需要在spring配置文件总配置相应的bean,以及设置相关的属性,通过反射的机制,让 spring容器来生成类的实例对象以及管理对象

控制反转

控制:创建对象的过程

反转:从开发者手动创建对象转变为spring自己创建对象

 

 

Spring创建对象的三种方法

1.无参构造器

//(1)传统方式:创建类,构建有参函数
public class Orders {
    //属性
    private String oname;
    private String address;

  }
<!--1 配置User对象创建-->
<bean id="user" class="com.atguigu.spring5.User"></bean>

2.有参构造

//(1)传统方式:创建类,构建有参函数
public class Orders {
    //属性
    private String oname;
    private String address;
    //有参数构造
    public Orders(String oname,String address) {
        this.oname = oname;
        this.address = address;
    }
  }
<!--(2)spring方式:有参数构造注入属性-->
<bean id="orders" class="com.atguigu.spring5.Orders">
    <constructor-arg name="oname" value="Hello"></constructor-arg>
    <constructor-arg name="address" value="China!"></constructor-arg>
</bean>

无法辨认精确的构造是 ,要指定index (按顺序来)

或type=“Java.lang.String” 注意:基本类型直接写,引用类型要写全路径 

3.工厂模式

设计模式:解决某种特定问题的代码解决方案

工厂设计模式的好处:之前我们创建对象是直接创建的,现在交给工厂统一处理

 

依赖注入三种实现方式:

1.有参构造

2.set方法注入

3.自动注入

 

bean的作用域

spring 每个对象默认都是单例的(有效范围 :同哟个bean 标签)

Scope属性可取值:

singleton:默认值单例的,使用ApplicationContext启动加载配置文件时实例化对象

prototype:原型,每次调用时实例化

另外 还有request 和 session

 

bean生命周期

 (1)通过构造器创建 bean 实例(无参数构造)

​ (2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)

​ (3)把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization

​ (4)调用 bean 的初始化的方法(需要进行配置初始化的方法)

​ (5)把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization

​ (6)bean 可以使用了(对象获取到了)

​ (7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法

 

注解

 

1、什么是注解

​ (1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值, 属性名称=属性值…)

​ (2)使用注解,注解作用在类上面,方法上面,属性上面

​ (3)使用注解目的:简化 xml 配置

2.Spring针对Bean管理中创建对象提供注解

1.@Compment  普通类

2.Service 用于业务逻辑层

3.Controller 用于控制层

4.@Repository 用于Dao层

上面的四个注解功能一样,都是用来创建对象的

3.基于注解方式实现对象

​ 第一步 引入依赖 (引入spring-aop jar包

​ 第二步 开启组件扫描

<!--开启组件扫描
 1 如果扫描多个包,多个包使用逗号隔开
 2 扫描包上层目录
-->
<context:component-scan base-package="com.atguigu"></context:component-scan>

 第三步 创建类,在类上面添加创建对象注解

//在注解里面 value 属性值可以省略不写,
//默认值是类名称,首字母小写
//UserService -- userService
@Component(value = "userService") //注解等同于XML配置文件:<bean id="userService" class=".."/>
public class UserService {
 public void add() {
 System.out.println("service add.......");
 }
}

4.开启组件细节扫描配置

<!--示例 1
 use-default-filters="false" 表示现在不使用默认 filter,自己配置 filter
 context:include-filter ,设置扫描哪些内容
-->


<context:component-scan base-package="com.atguigu" use-defaultfilters="false">
 <context:include-filter type="annotation" 
 expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

<!--代表只扫描Controller注解的类-->


<!--示例 2
 下面配置扫描包所有内容
 context:exclude-filter: 设置哪些内容不进行扫描
-->

<context:component-scan base-package="com.atguigu">
 <context:exclude-filter type="annotation"

expression="org.springframework.stereotype.Controller"/><!--表示Controller注解的类之外一切都进行扫描-->
</context:component-scan>

5.基于注解方式实现属性注入

(1)@AutoWired 根据属性类型进行自动装配

第一步 把 service 和 dao 对象创建,在 service 和 dao 类添加创建对象注解

第二步 在 service 注入 dao 对象,在 service 类添加 dao 类型属性,在属性上面使用注解

@Service
public class UserService {
 //定义 dao 类型属性
 //不需要添加 set 方法
 //添加注入属性注解
 @Autowired
 private UserDao userDao;
 public void add() {
 System.out.println("service add.......");
 userDao.add();
 }
}

//Dao实现类
@Repository
//@Repository(value = "userDaoImpl1")
public class UserDaoImpl implements UserDao {
    @Override
    public void add() {
        System.out.println("dao add.....");
    }
}

  (2) @Qualifier  根据属性名注入 和Autowired配合使用

一个接口有多个实现类 用Qualifier指定那个实现类

@Service
public class UserService {
 //定义 dao 类型属性
 //不需要添加 set 方法
 //添加注入属性注解
 @Autowired
 @Qualifier(value="userDaoImpl1")
 private UserDao userDao;
 public void add() {
 System.out.println("service add.......");
 userDao.add();
 }
}

//Dao实现类
@Repository(value = "userDaoImpl1")
public class UserDaoImpl implements UserDao {
    @Override
    public void add() {
        System.out.println("dao add.....");
    }
}

(3)@Resource 即可以根据名称注入,也可以根据类型注入,注意Resource不是Spring包中的而是扩展包中的,不建议用;

@Service
public class UserService {
 //定义 dao 类型属性
 //不需要添加 set 方法
 //添加注入属性注解
 //@Resource///根据名称注入
 @Resource(name = "userDaoImpl1")
 private UserDao userDao;
 public void add() {
 System.out.println("service add.......");
 userDao.add();
 }
}

//Dao实现类
@Repository(value = "userDaoImpl1")
public class UserDaoImpl implements UserDao {
    @Override
    public void add() {
        System.out.println("dao add.....");
    }
}

(4)@Value:注入普通类型属性

@Value(value = "abc")
private String name

 6、完全注解开发

​ (1)创建配置类,替代 xml 配置文件

@Configuration //作为配置类,替代 xml 配置文件
@ComponentScan(basePackages = {"com.atguigu"})
public class SpringConfig {
    
}

(2)编写测试类

@Test
public void testService2() {
 //加载配置类
 ApplicationContext context
 = new AnnotationConfigApplicationContext(SpringConfig.class);
 UserService userService = context.getBean("userService",
UserService.class);
 System.out.println(userService);
 userService.add();
}

 

 

 

Spring-AOP

1、AOP 基本概念

​ (1)面向切面编程(方面),利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得 业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

​ (2)通俗描述:不通过修改源代码方式,在主干功能里面添加新功能

​ (3)使用登录例子说明 AOP

 

 

web服务器

服务器是一种被动的操作,用来用户的请求和给用户响应

IIS 微软的

Tomcat

谈谈网站是如何进行访问的?

1.输入一个域名;回撤

2.检查本机的C:\Windows\System32\drivers\etcs\hosts配置文件下没有这个域名的映射;

   &有,直接返回对应的Ip地址,这个地址中有我们需要访问的web程序,可以直接访问 127.0.0.1

   &没有;去DNS服务器去找,找到的话就返回,找不到返回找不到

 

发布一个网站

 

 

 

 

传统MVC

M 模型 (dao :连接数据库 service:业务层)

V 视图(jsp)

V 控制器(servlet 接受前端的数据)

 

Spring MVC 是spring的一部分,底层还是servlet

 

注册servlet

 servlet配置文件

 

HandlerMapping 根据url请求先找到处理器,执行操作,把结果返回给DispatcherServlet

Controller

 jsp页面

 

原来的方式:http://localhost:8080/add?a=1&b=2

RestFul风格:http://localhost:8080/add/a/b

RestFul 风格的好处就是 提高安全性

@Controller
public class RestFulController {
    @RequestMapping("/add/{a}/{b}")
    public String test1(@PathVariable int a,@PathVariable int b, Model model){
        int res=a+b;
    model.addAttribute("msg","结果为"+res);
    return "test";
    }
}

如果不加描述,那么默认的请求方式是GET,当然还有其他方式 如 post,delete,put,get 详细写的出来的方法是下面的方式

@Controller
public class RestFulController {
    @RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)
    public String test1(@PathVariable int a,@PathVariable int b, Model model){
        int res=a+b;
    model.addAttribute("msg","结果为"+res);
    return "test";
    }
}

也可以进一步简化

@Controller
public class RestFulController {
    @GetMapping("/add/{a}/{b}")
    public String test1(@PathVariable int a, @PathVariable int b, Model model){
        int res=a+b;
        model.addAttribute("msg","结果为"+res);
        return "test";
    }
}

 

使用RESTful操作资源 :可以通过不同的请求方式来实现不同的效果!如下:请求地址一样,但是功能可以不同!

http://127.0.0.1/item/1 查询,GET

http://127.0.0.1/item 新增,POST

http://127.0.0.1/item 更新,PUT

http://127.0.0.1/item/1 删除,DELETE

 

结果跳转方式

ModelAndView

设置ModelAndView对象 , 根据view的名称 , 和视图解析器跳到指定的页面 .

页面 : {视图解析器前缀} + viewName +{视图解析器后缀}  即 /WEB-INF/jsp/test.jsp

<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
     id="internalResourceViewResolver">
   <!-- 前缀 -->
   <property name="prefix" value="/WEB-INF/jsp/" />
   <!-- 后缀 -->
   <property name="suffix" value=".jsp" />
</bean>

 

public class ControllerTest1 implements Controller {

   public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
       //返回一个模型视图对象
       ModelAndView mv = new ModelAndView();
       mv.addObject("msg","ControllerTest1");
       mv.setViewName("test");
       return mv;
  }
}

ServletAPI

通过设置ServletAPI , 不需要视图解析器 .

1、通过HttpServletResponse进行输出

2、通过HttpServletResponse实现重定向

3、通过HttpServletResponse实现转发

@Controller
public class ResultGo {

   @RequestMapping("/result/t1")
   public void test1(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
       rsp.getWriter().println("Hello,Spring BY servlet API");
  }

   @RequestMapping("/result/t2")
   public void test2(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
       rsp.sendRedirect("/index.jsp");
  }

   @RequestMapping("/result/t3")
   public void test3(HttpServletRequest req, HttpServletResponse rsp) throws Exception {
       //转发
       req.setAttribute("msg","/result/t3");
       req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,rsp);
  }

}

 

SpringMVC

通过SpringMVC来实现转发和重定向 - 无需视图解析器;

测试前,需要将视图解析器注释掉

<?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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
    <context:component-scan base-package="com.kuang.controller"/>
    <!-- 让Spring MVC不处理静态资源 -->
    <mvc:default-servlet-handler />
    <!--
    支持mvc注解驱动
        在spring中一般采用@RequestMapping注解来完成映射关系
        要想使@RequestMapping注解生效
        必须向上下文中注册DefaultAnnotationHandlerMapping
        和一个AnnotationMethodHandlerAdapter实例
        这两个实例分别在类级别和方法级别处理。
        而annotation-driven配置帮助我们自动完成上述两个实例的注入。
     -->
    <mvc:annotation-driven />

    <!-- 视图解析器 -->
<!--    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"-->
<!--          id="internalResourceViewResolver">-->
<!--        &lt;!&ndash; 前缀 &ndash;&gt;-->
<!--        <property name="prefix" value="/WEB-INF/jsp/" />-->
<!--        &lt;!&ndash; 后缀 &ndash;&gt;-->
<!--        <property name="suffix" value=".jsp" />-->
<!--    </bean>-->

</beans>

 转发:

@Controller
public class RestFulController {
    @GetMapping("/add/{a}/{b}")
    public String test1(@PathVariable int a, @PathVariable int b, Model model){
        int res=a+b;
        model.addAttribute("msg","结果为"+res);
        return "forward:/WEB-INF/jsp/test.jsp";
    }
}

 重定向:

    @GetMapping("/result/{a}/{b}")
    public String test2(@PathVariable int a, @PathVariable int b, Model model){
        int res=a+b;
        model.addAttribute("msg","结果为"+res);
        return "redirect:/index.jsp";
    }

重定向的的结果

通过SpringMVC来实现转发和重定向 - 有视图解析器;

重定向 , 不需要视图解析器 , 本质就是重新请求一个新地方嘛 , 所以注意路径问题.

可以重定向到另外一个请求实现 .

@Controller
public class RestFulController {
    @GetMapping("/add/{a}/{b}")
    public String test1(@PathVariable int a, @PathVariable int b, Model model){
        int res=a+b;
        model.addAttribute("msg","结果为"+res);
        return "test";  //转发
    }

    @GetMapping("/result/{a}/{b}")
    public String test2(@PathVariable int a, @PathVariable int b, Model model){
        int res=a+b;
        model.addAttribute("msg","结果为"+res);
        return "redirect:/index.jsp";//重定向
    }
}

数据处理

处理提交数据

1、提交的域名称和处理方法的参数名一致

提交数据 : http://localhost:8080/hello?name=kuangshen

处理方法 :

@RequestMapping("/hello")
public String hello(String name){
    System.out.println(name);
    return "hello";
}

后台输出 : kuangshen

 

2、提交的域名称和处理方法的参数名不一致

提交数据 : http://localhost:8080/hello?username=kuangshen

处理方法 :

//@RequestParam("username") : username提交的域的名称 .
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name){
    System.out.println(name);
    return "hello";
}

后台输出 : kuangshen

 

3、提交的是一个对象

要求提交的表单域和对象的属性名一致  , 参数使用对象即可

1、实体类

@Data
@AllArgsConstructor //有参构造
@NoArgsConstructor  //无参构造
public class User {
    private int id;
    private String name;
    private int age;
}

2、提交数据 : http://localhost:8080/mvc04/user?name=kuangshen&id=1&age=15

3、处理方法 :

@RequestMapping("/user")
public String user(User user){
    System.out.println(user);
    return "hello";
}

后台输出 : User { id=1, name='kuangshen', age=15 }

说明:如果使用对象的话,前端传递的参数名和对象名必须一致,否则就是null。

 

数据显示到前端

 

数据显示到前端

第一种 : 通过ModelAndView

我们前面一直都是如此 . 就不过多解释

public class ControllerTest1 implements Controller {

    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        //返回一个模型视图对象
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","ControllerTest1");
        mv.setViewName("test");
        return mv;
    }
}

 

第二种 : 通过ModelMap

ModelMap

@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
    //封装要显示到视图中的数据
    //相当于req.setAttribute("name",name);
    model.addAttribute("name",name);
    System.out.println(name);
    return "hello";
}

 

第三种 : 通过Model

Model

@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model){
    //封装要显示到视图中的数据
    //相当于req.setAttribute("name",name);
    model.addAttribute("msg",name);
    System.out.println(name);
    return "test";
}

 

对比

就对于新手而言简单来说使用区别就是:

Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解;

ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;

ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。

当然更多的以后开发考虑的更多的是性能和优化,就不能单单仅限于此的了解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值