Spring 学习记录(Day1)

一、配置Maven

在pom文件中添加依赖

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

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-parent</artifactId>
        <version>2.6.6</version>
    </parent>

    <groupId>com.easy</groupId>
    <artifactId>EasySpringA</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>
</project>

二、项目启动类

运行该类就运行了整个项目

在类名上添加注解@SpringBootApplication用于标记主配置类,并自动配置 Spring Boot 应用程序。

package com.easy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class EasySpringAApplication {
    //项目启动类  运行该类就运行了整个项目
    public static void main(String[] args) {
        SpringApplication.run(EasySpringAApplication.class,args);
    }
}
  • SpringApplication.run() 方法用于启动 Spring Boot 应用程序。它接受两个参数:
  • 第一个参数是要启动的应用程序的主类,即 EasySpringAApplication.class
  • 第二个参数是命令行参数数组 args,这些参数可以用来向应用程序传递命令行选项。

三、IOC   控制反转

容器:IOC

  Spring 通过IOC容器来管理所有Java对象的实例化和初始化,控制对象与对象之间的依赖关系。我们将有IOC容器管理的Java对象成为Spring Bean,它与使用关键字new创建的对象没有任何区别.

容器和代码之间的控制权反转,代码中不需要明文调用法来得到对象,只需要声明我们需要什么对象即可

反转

将对象的创建权利交出去,将对象和对象之间关系的维护权交出去,交给第三方容器负责。

容器中放Bean对象,使用map集合

通过BeanFactory工厂加反射实例化对象,然后进行初始化得到最终对象

BeanFactory:这是IOC容器的基本实现,是Spring内部使用的接口

依赖注入

DI:依赖注入实现了控制反转的思想

指的是应用程序在运行时依赖IOC容器来动态注入组件所需要的某个依赖对象,Spring的DI具体就是通过反射实现注入的,反射允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性等。

示例:

该类中需要EasyService类的对象,在这个类中只需要声明我们依赖EasyService这个类就可以,而不需要通过代码来主动获取EasyService类的对象
package com.easy.controller;

import com.easy.common.TestA;
import com.easy.service.EasyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
//@Scope(value = "request")
public class EasyController {

    //该类中需要EasyService类的对象
    //在这个类中只需要声明我们依赖EasyService这个类就可以
    //而不需要通过代码来主动获取EasyService类的对象


    //依赖注入DI  通过识别依赖关系注入对应的对象
    @Autowired
    EasyService easyS;
    @Autowired
    TestA testa;
    @RequestMapping("testb")
    public String testB(){
        testa.test();
        return "Easy method";
    }
    @RequestMapping("easya")
    public String easya(){
        System.out.println(easyS);
        return "new Service";
    }
    @RequestMapping("hello")
    public String hello(){
        return "java so easy";
    }
}

我们只需要声明一个EasyService类的对象,然后利用@Autowired注解来对该对象进行实例化。

注解

格式:@注解名称(属性1=属性值)

可以使用在类上面、属性上面、方法上面

常用的注解:

1. 组件扫描注解
@Controller:用于Web层,标识一个类为控制器组件,处理HTTP请求。
@RestController:组合了@Controller和@ResponseBody,用于RESTful Web服务,方法返回值直接作为响应体。
@Service:用于业务逻辑层,标识一个类为服务层组件,处理业务逻辑。
@Repository:用于数据访问层(DAO),标识一个类为持久层组件,处理数据访问。
@Component:通用组件注解,标识一个类为Spring组件,适用于其他功能类。

2. 配置注解
@Bean:在配置类中使用,定义一个Spring Bean。
@Configuration:标识一个类为配置类,包含Spring Bean的定义。

3. 其他常用注解
@Autowired:自动装配Bean,按类型注入。
@Qualifier:与@Autowired一起使用,按名称注入。
@Value:注入配置文件中的属性值。
@Scope:定义Bean的作用域,如单例(singleton)或原型(prototype)。
@PostConstruct:在Bean初始化后执行的方法。
@PreDestroy:在Bean销毁前执行的方法。
@RequestMapping:映射HTTP请求到控制器方法。

@GetMapping、@PostMapping、@PutMapping、@DeleteMapping:分别映射GET、POST、PUT、DELETE请求。
@RequestParam:绑定请求参数到方法参数。
@PathVariable:绑定URL路径变量到方法参数。
@RequestBody:绑定请求体到方法参数。
@ResponseBody:将方法返回值作为响应体。
@Transactional:声明式事务管理,标识一个方法或类需要事务支持。

示例:

@RequestMapping("名字")将地址映射成方法,执行和代码后,在浏览器中输入该名字作为地址即可访问。

在EasyController类中定义了一个方法,上面注解为@RequestMapping("hello")

运行代码,在浏览器上输入http://localhost:8080/hello 就能看到方法的返回值

 @RequestMapping("hello")
    public String hello(){
        return "java so easy";
    }

Bean的作用域

singleton 单例模式  一个对象  默认
prototype 原型模式  每次需要都来一个新的对象
request  web项目中请求作用域  每次请求都会创建一个新的对象
session 每次会话都会创建一个新的对象
GlobalSession 全局的

下面是示例

在TestA类中定义一个test方法,用来返回调用对象的地址

@Component

public class TestA {


    public void test(){
        System.out.println(this);
        System.out.println("test method");
    }
}

singleton 单例模式 一个对象 默认

在EasyController类和EasyAController中分别声明上类的对象并使用注解为其实例化,

@Autowired
    TestA testa;
    @RequestMapping("testb")
    public String testB(){
        testa.test();
        return "Easy method";
    }
@RestController

public class EasyAController {
    @Autowired
    TestA testa;
    @RequestMapping("testa")
    public String testA(){
        testa.test();
        return "EasyA method";
    }
}

执行代码后,分别输入各自的网址进行访问,查看日志

发现对象的地址是相同的,所以在未声明Bean的作用域时,默认是单例模式,只有一个对象

prototype 原型模式 每次需要都来一个新的对象

在上述实例TestA类上面利用@Scope声明Bean的作用域为prototype

@Scope(value= ConfigurableBeanFactory.SCOPE_PROTOTYPE)
//@Scope(value = "request")
@Component

public class TestA {


    public void test(){
        System.out.println(this);
        System.out.println("test method");
    }
}

然后再次执行上面的操作,得到的日志是

两个的对象地址不同,所以每次都需要一个新的对象

request web项目中请求作用域 每次请求都会创建一个新的对象

在EasyController类和EasyAController类上都定义Bean的作用域

@Scope(value = "request")
@RestController
public class EasyAController {
    @Autowired
    TestA testa;
    @RequestMapping("testa")
    public String testA(){
        testa.test();
        return "EasyA method";
    }
}

执行上面的操作,打印的日志为

注意:@Service注解是不能代替@Controller,@Service无法处理http请求

Bean的生命周期

创建EasyBean类

1)根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。

2)利用依赖注入完成 Bean 中所有属性值的配置注入。

3) 如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。

4)如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。

5) 当一个 Bean 实现了 ApplicationContextAware 接口并在 Spring 容器中被实例化时,Spring 容器会自动调用该 Bean 的 setApplicationContext 方法,并将应用程序上下文ApplicationContext作为参数传递进来

6)BeanPostProcessor 是 Spring 框架中的一个重要接口,它允许开发者在 Spring 容器创建和初始化 bean 的过程中,对 bean 进行自定义处理。这包括在 bean 实例化之后、属性设置之前(postProcessBeforeInitialization 方法),以及在 bean 初始化之后(postProcessAfterInitialization 方法)执行自定义逻辑

Spring 容器在创建和初始化每一个 bean 时,都会调用 CustomBeanPostProcessor 中的这两个方法,允许你进行自定义处理

创建一个EasyBeanProcesser类实现BeanPostProcessor接口

7)InitializingBean 是 Spring 框架中的一个接口,它定义了一个 afterPropertiesSet 方法。当 Spring 容器创建 bean 的所有属性都被设置完成后,会调用这个方法。

8)如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。

创建一个EasyConfig类

9)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。

10)如果在 <bean> 中指定了该 Bean 的作用范围为 scope="singleton",则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在 <bean> 中指定了该 Bean 的作用范围为 scope="prototype",则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。

11)如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁

下面是完整代码以及执行时打印的日志

package com.easy.common;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

//@Component("easybean")
public class EasyBean implements BeanNameAware , BeanFactoryAware, ApplicationContextAware, InitializingBean , DisposableBean {
    public EasyBean(){
        System.out.println("1---构造方法");
    }

    public void init(){
        System.out.println("8---init Method");
    }
    TestA testa;
    @Autowired
    public void setTesta(TestA testa){
        System.out.println("2---注入属性");
        this.testa=testa;
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("3---BeanNameAware接口的 setBeanName方法"+name);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("4---BeanFactoryAware接口的setBeanFactory方法"+beanFactory);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("5---ApplicationContextAware接口的setApplicationContext方法"+applicationContext);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("7---InitializingBean接口的afterPropertiesSet方法");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("easybean被回收了");
    }
}

  • 25
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值