Spring + Spring Boot


Spring

一、概述

Spring功能非常丰富,核心的两大功能是:IOC、DI、AOP。
IOC:控制反转,指把创建对象的过程交给Spring
DI:依赖注入,指把对象间的依赖关系自动维护
AOP:面向切面编程,它是补充了OOP(面向对象)的不足

二、IOC(控制反转)

是指把创建对象管理对象的过程交给了Spring框架

1、IOC的XML实现方式

创建Maven的Module
导入jar包(被Spring Boot整合了)
创建IOCDemo类
public class IOCDemo {
    public void ioc() {
        System.out.println("我是Spring IOC的XML实现方式");
    }
}
创建applicationContext.xml配置文件

在这里插入图片描述

<?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"
       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">

    <!--配置Bean的信息-->
    <!--
        id:作为这个bean的唯一标识,我们会通过这个获取,可以自行取名
        class:类的全路径,找到需要的类
        这个配置文件配置后,就会直接 new
        IOC -> {"IOCDemo",new IOCDemo()},Map的{K,V}形式
        底层反射
    -->
    <bean id="ioc" class="com.sgz.iocz.IOCDemo">

    </bean>
    
</beans>

创建测试类

public class TestIOCAndDI {
    @Test
    public void test() {
        // 1、读取配置文件
        ClassPathXmlApplicationContext spring
                = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 2、直接getBean,会得到new对象的地址值
        //  Object ioc = spring.getBean("ioc"); // 这里的 ioc 是 xml配置文件里的 id
        // 因为ioc()方法在 IOCDemo,所有需要转换类型,并不在Object类中
        IOCDemo ioc = (IOCDemo) spring.getBean("ioc");
        // 3、调用该类的方法
        ioc.ioc();
    }
}

2、IOC的注解实现方式

创建IOCDemo02 类
/*
    三种注解可以完成IOC: @Component、@Controller、@Service
    Spring 框架提供的用来完成IOC,设置这些注解后,会被扫描到
    以 Map -> {K,V}形式,ioc -> {"iOCDemo02",new IOCDemo02()}
 */
@Component("my")   // 自定义bean的名字(对象名),我们就使用这名字就行了,不需要再使用默认的名字
// @Component
// @Controller
// @Service
public class IOCDemo02 {
    public void ioc() {
        System.out.println("我是Spring IOC的注解实现方式");
    }
}
修改applicationContext.xml配置文件
<?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"
       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">

    <!--IOC包扫描-->
    <!--
        配置包扫描
        它会帮我们new对象,IOCDemo02 iOCDemo02 = new IOCDemo02();
        会自动生成默认名,一般都是首字母小写(有时候不会),注意看控制台打印提示对象名,也可以通过注解自定义对象名
        base-package:指定一个包的路径,它只会扫描类中带有 @Component、@Controller、@Service 三者之一注解的
        包可以 com.sgz.io  扫描该包下加了注解的类
              com.sgz     扫描该包下所有包的类
              com         扫描该包下所有包的类
    -->
    <context:component-scan base-package="com.sgz.iocz">

    </context:component-scan>

</beans>
测试
public class TestIOCAndDI {
    @Test
    public void test() {
        // 1、读取配置文件
        ClassPathXmlApplicationContext spring
                = new ClassPathXmlApplicationContext("applicationContext.xml");
      // 2、直接getBean,会得到new对象的地址值           
        // IOCDemo02 iOCDemo02 = (IOCDemo02) spring.getBean("IOCDemo02");
        IOCDemo02 iOCDemo02 = (IOCDemo02) spring.getBean("my"); //使用自定义bean名(对象名)
       // 3、调用该类的方法
        iOCDemo02.ioc();
    }
}

三、DI(依赖注入)

1、概述

是指对象间的依赖关系,绑定两个类之间的关系,可以由框架来完成。

2、使用传统方式实现DI

创建Boss类
public class Boss {

    String name = "我是老板";

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

创建Staff类
public class Staff {

    String name = "我是员工";

    // 1、绑定两个类间的关系,在一个类中定义另外一个类的变量
    private Boss boss;

    // 2、get / set 方法
    public Boss getBoss() {
        return boss;
    }

    public void setBoss(Boss boss) {
        this.boss = boss;
    }

    // toString用来测试显示数据
    @Override
    public String toString() {
        return "Staff{" +
                "name='" + name + '\'' +
                ", boss=" + boss +
                '}';
    }
}

配置包扫描
<?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"
       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">

    <!--包扫描-->
    <!--
        配置包扫描
        它会帮我们new对象,IOCDemo02 IOCDemo02 = new IOCDemo02();  Demo demo = new Demo();
        会自动生成默认名,一般都是首字母小写(有时候不会),注意看控制台打印提示对象名,也可以通过注解自定义对象名
        base-package:指定一个包的路径,它只会扫描类中带有 @Component、@Controller、@Service 三者之一注解的
        包可以 com.sgz.io  扫描该包下加了注解的类
              com.sgz     扫描该包下所有包的类
              com         扫描该包下所有包的类
    -->
    <context:component-scan base-package="com.sgz.diz">

    </context:component-scan>

</beans>
测试
public class TestIOCAndDI {
    @Test
    public void test() {
        // 1、读取配置文件
        ClassPathXmlApplicationContext spring
                = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 2、实现传统DI
        // Spring的DI传统实现(get,set)
        Boss boss = new Boss();
        System.out.println(boss);   // Boss{name='我是老板'}
        Staff staff = new Staff();  // Staff{name='我是员工', boss=null}
        System.out.println(staff);
        // DI:把两个对象间的关系依赖注入,实现DI
        staff.setBoss(boss);
        System.out.println(staff);  // Staff{name='我是员工', boss=Boss{name='我是老板'}}
    }
}

3、使用Spring注解实现DI

使用前必须加上@Component

注解简介

@Autowired:Spring中DI注解

创建Teacher类
@Component
public class Teacher {

    String name = "我是老师";

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

创建Student类
@Component
public class Student {

    String name = "我是学生";
    /*
        自动装配,该注解可以实现DI,不需要 get / set
        使用DI前,必须有IOC,才可以DI,Component -> Autowired
     */
    @Autowired
    Teacher teacher;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", teacher=" + teacher +
                '}';
    }
}
创建配置文件,包扫描
<?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"
       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">
       
    <!--包扫描-->
    <!--
        配置包扫描
        它会帮我们new对象,IOCDemo02 IOCDemo02 = new IOCDemo02();  Demo demo = new Demo();
        会自动生成默认名,一般都是首字母小写(有时候不会),注意看控制台打印提示对象名,也可以通过注解自定义对象名
        base-package:指定一个包的路径,它只会扫描类中带有 @Component、@Controller、@Service 三者之一注解的
        包可以 com.sgz.io  扫描该包下加了注解的类
              com.sgz     扫描该包下所有包的类
              com         扫描该包下所有包的类
    -->
    <context:component-scan base-package="com.sgz.diz">

    </context:component-scan>

</beans>
测试
public class TestIOCAndDI {
    @Test
    public void test() {
        // 1、读取配置文件
        ClassPathXmlApplicationContext spring
                = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 2、Spring的DI注解实现
        Student student = (Student) spring.getBean("student");
        System.out.println(student);	// Student{name='我是学生', teacher=Teacher{name='我是老师'}}

    }
}

总结

bean名不能一样

四、Lombok

1、作用

简化了Model层的代码的编写。
以前pojo类/实体类,需要自己提供set、get、toString、equals、hashCode。
Lombok通过各种注解,简化了以上操作。

2、注解简介
  1. @Data:会自动生成set、get、toString、equals、hashCode
  2. @NoArgsConstructor:自动生成无参构造
  3. @AllArgsConstructor:自动生成全参构造
  4. @Accessors(chain = true):开启链式编程
3、使用步骤
3.1、在IDEA里安装插件(高版本IDEA已经自动安装好,直接使用即可)

在这里插入图片描述
在这里插入图片描述

3.2、修改pom.xml文件,添加Lombok的jar包依赖,dependencies 标签内配置
 <!--支持lombok-->
 <dependencies>
          <dependency>
               <groupId>org.projectlombok</groupId>
               <artifactId>lombok</artifactId>
               <version>1.18.24</version>
           </dependency>
    </dependencies>
3.3、修改pojo包中的Shopping类
修改前
public class Shopping {

    private Integer id;
    private String name;
    private Double price;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Shopping{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

修改后
@Data   // 自动生成 get set toString equals hashCode
@NoArgsConstructor  // 自动生成无参构造
@AllArgsConstructor // 自动生成有参构造
@Accessors(chain = true)    // 开启链式编程
public class Shopping {

    private Integer id;
    private String name;
    private Double price;

}
3.4、创建TestLombok测试类
修改前
public class TestLombok {

    @Test
    public void test(){
        Shopping shopping = new Shopping();
        shopping.setId(1);
        shopping.setName("辣条");
        shopping.setPrice(2.5);
        System.out.println(shopping.getId());
        System.out.println(shopping.getName());
        System.out.println(shopping.getPrice());
        System.out.println(shopping);
    }
}
修改后
public class TestLombok {

    @Test
    public void test02(){

        Shopping shopping = new Shopping();
        shopping.setId(2);
        shopping.setName("可乐");
        shopping.setPrice(3.5);
        System.out.println(shopping.getId());
        System.out.println(shopping.getName());
        System.out.println(shopping.getPrice());
        System.out.println(shopping);

        Shopping shopping1 = new Shopping(3,"雪碧",3.5);
        System.out.println(shopping1);

        Shopping shopping2 = new Shopping();
        // 使用 Lombok 的链式编程
        shopping2.setId(4).setName("鸡爪子").setPrice(2.5);
        System.out.println(shopping2);

    }
}

五、Spring MVC 与 Spring两个框架整合

1、创建网页
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>SpringMVC和Spring框架整合</title>
	</head>
	<body>
		
		<a href="http://localhost:8080/two/get">点击请求服务器的数据</a>
		
	</body>
</html>
2、创建包

在这里插入图片描述

3、创建启动类RunApp
// 自动配置了包扫描:默认从启动类所在的包以及它的子包开始扫描
@SpringBootApplication
public class RunApp {
    public static void main(String[] args) {
        SpringApplication.run(RunApp.class);
    }
}

4、创建pojo包的Book类
/**
 * 作者:沈公子
 * 日期:2022/7/22 - 14:25
 * 需求:模型层(M)
 */
@Data   // 自动生成 get set toString equals hashCode
@NoArgsConstructor  // 自动生成无参构造
@AllArgsConstructor // 自动生成含参构造
@Accessors(chain = true)          // 开启链式编程
public class Book {

    private Integer id;
    private String name;
    private String type;
    private Double price;

}

5、创建controller包的BookController类
/**
 * 作者:沈公子
 * 日期:2022/7/22 - 14:27
 * 需求:控制层(C)
 */
@RestController
@RequestMapping("two")
public class BookController {

    // 想用那个类的功能,就 DI 过来(get / set)
    // 调用 service 层的代码 DI
    @Autowired
    private BookServiceImpl service;
    // 也可以使用接口
    @Autowired
    private BookService service1;

    @RequestMapping("get")
    public Object start() {
        // 找 service 要数据,返回结果给浏览器
        return service.get();
    }

}
6、创建service包的BookService接口
/**
 * 作者:沈公子
 * 日期:2022/7/22 - 14:29
 * 需求:Service接口
 */
public interface BookService {

    // 接口里的方法都是抽象方法,而且都是public的,特殊的可以定义 default 和 static
    // 获取书包数据
    Book get();
    // 增删改需不要返回值
    // void add(Book book);
}

7、创建service包的BookServiceImpl实现类
/**
 * 作者:沈公子
 * 日期:2022/7/22 - 14:30
 * 需求:Service实现类
 */
// IOC,使用DI前,需要IOC
@Component
public class BookServiceImpl implements BookService {

    @Override
    public Book get() {
        // 给浏览器准备数据
        Book book = new Book();
        // Lombok的链式编程
        book.setId(1).setName("SMM开发基础").setType("IT类").setPrice(60.5);
        return book;
    }
}

8、测试

在这里插入图片描述

在这里插入图片描述

六、Spring AOP(面向切面编程)

1、概念

AOP是一个面向切面编程的思想,它补充了面向对象的不足。
实现的效果:对方法的增强,本质上就是在执行方法的前后添加功能。
经典的使用场景:统计性能分析、权限管理、事务管理、日志、缓存…
切面:本质上就是一个类
通知:本质上就是一个方法,分成五类
具体五种为:
1. 前置通知before,方法执行前要执行的功能
2. 后置通知after,方法执行后要执行的功能
3. 环绕通知around,方法执行前后都要的执行的功能
4. 返回后通知argerReturning
5. 异常通知afterThrowing
切点:指定哪些类的哪些方法要用通知的功能。

2、AOP注解

  1. @Aspect:表示是一个切面类
  2. @Before:表示是一个前置通知
  3. @After:表示是一个后置通知
  4. @Around:表示是一个环绕通知
  5. @PointCut:表示切点

3、使用过程

3.1、导入jar包,pom.xml
        <!--AOP依赖包-->
 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
            <version>2.7.0</version>
        </dependency>
    </dependencies>
3.2、代码
// IOC才能调用里面的方法
@Service
// 标记着这是一个 AOP 的类:切面
@Aspect
public class AOPAspect {

    // 1、切点(指定具体要用通知的类或者方法)
    // 切点表达式:*是通配符,..表示0~n个
    // 方法返回值 包路径 子包 类名 方法名 参数列表
    @Pointcut("execution( * com.sgz.service..*.*(..))")
    public void point() {

    }

    // 2、通知(是一个方法自定义功能)
    @Around("point()")  // 是一个环绕通知
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {

        long time = System.currentTimeMillis();        // 计时开始
        // 去执行你的业务方法
        Object o = joinPoint.proceed();
        // long end = System.currentTimeMillis();
        time = System.currentTimeMillis() - time;        // 计时结束

        // 获取类名和方法名
        String methodname= joinPoint.getTarget().getClass().getName()+"."+joinPoint.getSignature().getName();

        // end - start
        System.out.println(methodname+"方法执行时间是:" + time);
        return o;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值