SpringDay(01)

课程介绍

  1. Spring
  2. SpringMvc 代替Servlet
  3. Mybatis 代替JDBC
  4. SSM整合
  5. SpringBoot
  6. 单体稻草项目
  7. 微服务(SpringCloud)
  8. 微服务组件(Redis,ES,Kafka)

什么是框架

框架就是第三方编写的项目半成品

使用上也是下载一些jar包到本地

为什么需要框架

将一些本来很复杂的操作简化

使用框架时,前期先不纠结内部原理和源码

Spring概述

什么是Spring

实现IOC和DI工具

IOC:控制翻转

普通的主动控制:需要什么对象时自己实例化

IOC控制翻转:需要什么从Spring容器中取

Spring提供了"Spring容器"

为什么需要Spring

将程序中所有需要的组件(对象)都保存在Spring容器中

在需要的时候获得,如果Spring容器中保存的对象变化,获得的代码不不需要修改的

这样就能提高程序的可维护性和可扩展性

怎么使用Spring

创建一项目

pom.xml文件

<?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>org.example</groupId>
    <artifactId>SpringDay01</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <!-- 设置 JDK 版本为 1.8 -->
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
        <!-- 设置编码为 UTF-8 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
    </properties>
    <dependencies>
        <!-- Spring Context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.2</version>
        </dependency>
    </dependencies>

</project>

新建一个类(简单的就行)

public class Stu {
    
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Stu{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

使用Spring的第一个步骤

新建一个类,我们暂时名称为Config

//Spring框架的配置类
public class Config {

    /**
     * @Bean 注解的方法:
     * 表示这个方法的返回值会注入到Spring容器中
     * 注入的对象,可以在该方法中创建并赋值
     * 这个方法的方法名默认情况下是这个对象的ID(名字)
     * @return
     */
    @Bean
    public Stu student(){
        Stu stu=new Stu();
        stu.setName("曹操");
        stu.setAge(60);
        return stu;
    }

}

第二个步骤

新建一个测试类,从Spring容器中获得这个对象

public class SpringTest {

    public static void main(String[] args) {
        //想启用Spring还需要依据我们编写的Spring配置类来创建对象
        AnnotationConfigApplicationContext ctx=
                new AnnotationConfigApplicationContext(Config.class);
        //实例化上面对象参数是配置类的反射
        //原因是反射中包含这个类中所有内容的信息,方便Spring处理

        //将对象从Spring容器中获取
        //现在用两个参数,第一个参数是获取对象的id
        //第二个参数是获取对象的类型
        Stu caocao=ctx.getBean("student",Stu.class);
        //输出这个对象
        System.out.println(caocao);
        ctx.close();
    }
}

习题

按照上面的步骤

将你同桌的同学信息注入到Spring容器中

并编写测试类获取输出

Junit 单元测试

什么是Junit

java 单元(unit) 测试

代替我们编写的main方法对我们编写的代码进行测试

为什么需要Junit

我们每测试一个代码都需要编写一个main方法比较麻烦

Junit可以一个类编写多个测试方法

测试类和我们的程序类分离

而且Junit可以有更详细的测试报告

怎么去使用

pom.xml文件中导入依赖

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
</dependency>

在test文件夹下新建测试类

新建的类中使用@Test表示要测试的方法

//这是一个测试类
//类名是随意的
public class TestCase {
    //要想可以测试,编写一个注解
    //@Test标注的方法就是一个可以进行测试的方法
    @Test
    public void test(){
        System.out.println("hello");
    }
    //一个测试类中可以编写多个测试方法
    @Test
    public void springTest(){
        AnnotationConfigApplicationContext ctx=
                new AnnotationConfigApplicationContext(Config.class);
        Stu caocao=ctx.getBean("student",Stu.class);
        System.out.println(caocao);
        ctx.close();
    }

}

Junit提供了测试之前和测试之后运行代码的注解

能够减少测试前和测试后一定会运行的代码

我们现在的代码中

  AnnotationConfigApplicationContext ctx=
                new AnnotationConfigApplicationContext(Config.class);

是测试前运行的

ctx.close();

是测试后运行的

可以将他们简化

//这是一个测试类
//类名是随意的
public class TestCase {

    AnnotationConfigApplicationContext ctx;
    //@Before注解的方法会在具体测试代码运行之前运行
    @Before
    public void init(){
        ctx=new AnnotationConfigApplicationContext(Config.class);
        System.out.println("Before");
    }
    //@After注解的方法会在具体测试代码运行之后运行
    @After
    public void destroy(){
        ctx.close();
        System.out.println("After");
    }


    //要想可以测试,编写一个注解
    //@Test标注的方法就是一个可以进行测试的方法
    @Test
    public void test(){
        System.out.println("hello");
    }

    //一个测试类中可以编写多个测试方法
    @Test
    public void springTest(){
//        AnnotationConfigApplicationContext ctx=
//                new AnnotationConfigApplicationContext(Config.class);
        Stu caocao=ctx.getBean("student",Stu.class);
        System.out.println(caocao);
//        ctx.close();
    }

}

java程序类规范

java bean实际上时java程序中对类约定的定义规则

是一套规范,有了这套规范,方便使用和交流

  1. 所有类必须定义在包里
  2. 除非特殊原因一定要有无参构造
  3. 要实现序列化接口
  4. 所有属性需要使用getXxx和SetXxx的规则

JavaBean有哪些规范?

  1. 实现Serializable接口
  2. 提供无参构造器
  3. 为私有属性提供 getter / setter /isXXX 方法
  4. 可以有少量的业务实现

Spring的组件扫描

使用组件扫描注入对象

我们之前的案例中使用的是@Bean来进行的注入

这种注入是需要编写代码的

如果需要实例化后为属性赋值或者类似操作,我们可以使用@Bean来注入到Spring容器

但是有些类没有需要赋值的属性,那么使用@Bean注入就比较麻烦了

可以使用@Component(英文:“组件”)

来标记在需要注入的类上,这样Spring内部可以自动注入

注入对象的id名是类名首字母小写的状态

例如:DragonBlade —> dragonBlade

但是如果类名是连续两个或以上的大写字母,那么id就是类名

例如:AWPGun —> AWPGun

注意光在类上加注解是不够的

还需要在Config类上加扫描的注解

小结组件扫描注入过程

1.在要注入的类上加注解@Component

2.注意类名生成的ID

3.别忘了在Config类上编写@ComponentScan扫描目标包

Spring提供多种注解注入对象

@Component

@Controller

@Service

等多种注解都可以响应组件扫描将这个类注入到Spring容器

一个功能分这么多注解的原因并不是注解的功能不同

区别仅在于他们单词的意思不同

我们使用的时候根据当前类的角色使用不同单词来注入

自定义组件的id

使用@bean注入时可以使用下面的方法自定义注入Spring容器的id

@Bean("caocao")

使用@Component以及其他可以组件注入的注解时

使用下面方法自定义注入Spring容器的id

@Component("db")

习题:

将之前编写的习题同桌同学的信息对象id自定义为"classmate"

组件扫描:

定义一个Axe(斧子类)

其中有固定的属性值为:private String name=“斧子”;

以及toString方法

使用组件扫描相关知识注入这个对象

并在测试类中获得并输出

可以自定义id:例如:fuzi

Spring容器对Bean的管理策略

为了丰富Spring对注入的对象管理和使用,Spring提供了

一系列管理策略

管理Bean的作用域

什么是作用域

我们将Spring中Bean的作用域分为两种

1.单例(singleton):

当前这个注入的对象在Spring容器中只有1个

无论何时获取,均获得这同一个对象

Spring默认情况下管理Bean就是单例的

2.原型(prototype):

原型模式下,我们使用的注入只是一个模板

每次获得对象时,新实例化对象返回给我们的调用

所以每次获得得对象不是同一对象,互相没有关联

单例的好处:

节省内存,但是不能记录不同的属性或状态

原型的好处:

可以获得不同的对象,保存不同的属性或状态,但是频繁获取会制造过多对象,浪费内存

设置方式:

单例是默认的,无需设置

原型模式

@Bean注入

    @Bean("caocao")
    @Scope("prototype")//原型
    public Stu student(){
        Stu stu=new Stu();
        stu.setName("曹操");
        stu.setAge(60);
        return stu;
    }

组件扫描

@Component("db")
@Scope("prototype")//原型
public class DragonBlade {
	....
}

懒惰初始化

单例下我们在实例化Spring容器时就会自动创建单例的对象

如果程序中不使用这个对象,反而会造成内存的浪费

我们怎么弥补这个缺点呢?(这个情况只针对单例的对象)

使用懒惰初始化

懒惰初始化就是在程序使用到这个对象时在实例化这个对象的策略

一般用于不确定是否使用的对象使用注解

@Lazy

@Bean注入方式

    @Bean("caocao")
    //@Scope("prototype")
    @Lazy//懒惰加载
    public Stu student(){
        Stu stu=new Stu();
        stu.setName("曹操");
        stu.setAge(60);
        return stu;
    }

组件扫描注入方式

@Component("db")
//@Scope("prototype")
@Lazy//懒惰初始化
public class DragonBlade {
...
}

习题:

创建一个新的包 包中新建一个类(Soldier)士兵

类中有属性姓名和血型,编写无参构造,和get\set\toString

创建Config类使用@Bean注入两个士兵 分别是"瑞恩",“A型” “花木兰”,“O型”

1.编写测试类 在测试类中获得瑞恩和花木兰对象 并输出测试 观察测试结果

2.将花木兰设置为懒惰初始化 并输出测试 观察测试结果

3.将瑞恩设置为原型模式 可以尝试获得多个瑞恩对象,并输出测试 观察测试结果

最后使用组件扫描注入两把武器,分别是AK47类和KAR98K,代码参照青龙偃月刀

,自行编写测试

使用@Import导入其它配置文件

在实际开发中

一个项目可以有多个配置类

程序运行时他们都需要加载

最简单的办法就是在ACAC构造方法里使用,分割编写多个配置类的反射

例如

ctx=new AnnotationConfigApplicationContext(
                Config.class, Config2.class);

但是上面的代码在新增更多配置类时还是需要维护的

name我们可以在某个配置类中通过添加@Import注解的方式,不修改具体代码来添加配置类

@ComponentScan("cn.tedu.hero")
@Import({Config2.class})//同时加载Config2这个类中的Spring配置
public class Config {
....
}

Spring框架技术概要

我们学习Spring分一下几个模块

1.IOC控制反转

2.DI依赖注入

3.AOP面向切面编程(项目阶段讲)

依赖的概念

依赖就是某个业务(方法)在执行时需要使用到其它物料(对象)

执行这个业务的对象和需要用到的物料就叫做依赖关系

人写字业务依赖笔对象

关羽完成战斗业务需要青龙偃月刀

依赖关系在程序中声明

执行业务的类中声明被依赖对象类型的属性

上面的文字转换成代码如下

public class Hero implements Serializable {
    private String name;
    private int power;

    //在Hero类中声明了一个DragonBlade类型的属性
    //表示Hero类依赖DragonBlade
    private DragonBlade dragonBlade;
    
    public void fight(){
    // 战斗业务......
    }
 }

在测试类中,将执行业务的对象和被依赖对象建立依赖关系

将青龙偃月刀赋值到关羽的青龙偃月刀属性中

代码如下

    @Test
    public void fightTest(){
        Hero h=ctx.getBean("guanYu",Hero.class);
        DragonBlade db=ctx.getBean("blade",DragonBlade.class);
        h.setDragonBlade(db);
        h.fight();
    }

输出结果

关羽使用青龙偃月刀战斗

习题:

新建一个包

创建一个Person(人)类

人类有String name属性

还有Pen pen(钢笔)属性 这个Pen类是自己创建的,name就是钢笔,toString方法返回"钢笔"

还有一个写字方法write()

这个写字方法输出"<谁>使用<什么笔>写字"

最后新建一个测试类

在测试类中从Spring容器中获得人和笔,将笔对象赋值为人的笔类型的属性之后调用write方法

可以下载了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值