Spring 详解(学习总结)


一、Spring是什么?

我们所说的 Spring 指的是 Spring Framework (Spring 框架),它可以让Java企业级的应用程序开发起来更简单。

Spring的概念: Spring 是包含了众多工具方法的 IoC 容器。

容器 就是容纳物品的装置,比如 List/Map ->是数据存储容器 , Tomcat ->是 Web容器,

将对象存放到容器中的好处
将对象存储在 IoC 容器相当于将以后可能⽤的所有⼯具制作好都放到仓库中,需要的时候直接取就⾏了,⽤完再把它放回到仓库。⽽ new 对象的⽅式相当于,每次需要⼯具了,才现做,⽤完就扔掉了也不会保存,下次再⽤的时候还得重新做,这就是 IoC 容器和普通程序开发的区别。

1.Spring IoC(Inversion of Control)

Spring 是⼀个 IoC 容器,说的是对象的创建和销毁的权利都交给 Spring 来管理了,它本身又具备了存储对象和获取对象的能力。

IoC = Inversion of Control(控制反转) 之前是上级对象创建并控制下级对象, 通过控制权发生反转后,是将下级对象注入到当前对象中,下级的控制权不再由上级类控制了, 这样的好处就是即使下级类发生任何变化,当前类都是不受影响的,这就是典型的控制反转。

Spring IoC 容器具备的两个最基础的功能为

  • 将对象存入到Spring容器。
  • 从Spring容器中取出对象。

也就是说学习Spring最核心的功能,就是要学习如何将对象存到 Spring 中,然后再从Spring 中获取对象的这个过程。

2.DI (Dependency Injection) 概念说明

DI(Dependency Injection):依赖注入,当 IoC 容器在运行期间,动态的将某种依赖关系注入到对象之中。
所以,依赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过引⼊ IoC 容器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦。

二、Spring 的创建和使用

在 Java 语言中对象也叫作Bean,接下来遇到的对象就称为 Bean。

1.创建 Spring 项目

使用 Maven 方式来创建一个 Spring 项目,创建 Spring 项目和 Servlet 类似。

1.1 创建一个 Maven 项目

center

点击 Next

点击Finish

1.2 添加 Spring 框架支持
在项目的 pom.xml 中添加 Spring 框架的支持,xml 配置如下:

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.28</version>
        </dependency>

    </dependencies>

1.3 添加启动类

最后在创建好的项目 java 文件夹下创建一个启动类, 包含 main 方法即可:

public class App {
    public static void main(String[] args) {
        
    }
}

2.存储 Bean 对象

2.1 创建Bean
所谓 Bean 就是 Java 语言中的一个普通对象,

public class User {
    private String userName="张三";
    public void sayHi(){
        System.out.println("hello");
    }
}

2.2 将 Bean 注册到容器

在创建好的项目中添加 Spring 配置文件 spring-config.xml, 将此文件放到 resources 的根目录下,如下图:

这里给出 Spring 配置文件的内容(内容格式固定,复制粘贴到自己项目中即可):

<?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:content="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">
</beans>

接下来,将 User 对象注册到 Spring 中: 在< beans> 中添加如下配置:

     <bean id="user" class="User"></bean>

3.获取并使用 Bean 对象

3.1 得到 Spring 上下文对象

两种方法:
(1)Spring 上下文对象可用 ApplicationContext

// 1.得到 Spring 的上下⽂对象,创建的时候需要配置 Spring 配置信息
ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");

(2)除了 ApplicationContext 之外,我们还可以使⽤ BeanFactory 来作为 Spring 的上下⽂,如下代码所
示:

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("springconfig.xml"));

ApplicationContext VS BeanFactory

  • 继承关系和功能⽅⾯来说:Spring 容器有两个顶级的接⼝:BeanFactory 和ApplicationContext。其中BeanFactory 提供了基础的访问容器的能⼒,⽽ ApplicationContext属于 BeanFactory 的⼦类,它除了继承了 BeanFactory 的所有功能之外,它还拥有独特的特性,还添加了对国际化⽀持、资源访问⽀持、以及事件传播等⽅⾯的⽀持。
  • 从性能⽅⾯来说:ApplicationContext 是⼀次性加载并初始化所有的 Bean 对象,⽽
    BeanFactory 是需要那个才去加载那个,因此更加轻量。

PS:⽽ ClassPathXmlApplicationContext 属于 ApplicationContext 的子类,
拥有ApplicationContext 的所有功能,是通过 xml 的配置来获取所有的 Bean 容器的。

3.2 获取及使用指定的 Bean 对象

public class App {
    public static void main(String[] args) {
        // 1.得到 Spring 的上下⽂对象,创建的时候需要配置 Spring 配置信息
        ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
        User user=(User) context.getBean("user");
        user.sayHi();
    }
}

注意事项
getBean 中的参数要和 spring-config.xml 中bean 的id 一一对应

三、Spring 更简单的存取对象

1. 存储 Bean 对象

之前存储 Bean 时,需要在 spring-config.xml 中添加一行 bean 注册内容才行,现在只需要一个注解就行。

1.1 前置工作:配置扫描路径(重要)

在 spring-config.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:content="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">
    <content:component-scan base-package="com.spring.demo"></content:component-scan>
</beans>

只有在 base-package 包下的类,并且添加了注解才能被正确的识别并保存到 Spring 中。

1.2 添加注解 存储Bean对象

此处有两种注解类型可以实现:

  1. 类注解:@Controller (控制器存储) :表示业务逻辑层
                  @Service (服务存储):服务层
                  @Repository (仓库存储):持久层
                  @Component (组件存储)
                  @Configuration (配置存储):配置层

  2. 方法注解:@Bean
    类注解是直接添加到某个类上的,而方法注解是放到某个方法上。
    但是使用 @Bean 时必须搭配类注解使用。
    使用 @Bean 注解 并重命名,这个重命名的 name 属性是一个数组,将此 Bean对象注册到 Spring 容器里可以有多个名字

@Component
@Order(40)   //控制注入的顺序  值越小,  优先级越高
public class UserBeans {
    @Bean(name = {"user","u1"})
//    @Bean(value = "user1")
    public User user1(){
        User user=new User();
        user.setUserid(1);
        user.setUsername("张三");
        user.setPassword("123456");
        user.setAge(18);
        return user;
    }
}

2. 获取 Bean 对象 (对象装配、对象注入)

获取 bean 对象叫做对象装配,是把对象从 spring 中取出来放到某个类中,也叫对象注入

对象注入的实现方法有3种:

  1. 属性注入 :@Autowired 、@Resource
  2. 构造方法注入
  3. Setter 注入

2.1 属性注入
使用 @Autowired 实现,将 Service 类注入到 Controller 类中,之后就可以在 Controller 类中使用 Service 对象:

@Controller
public class UserController {

    //1.属性注入
    @Autowired //注入对象(更加简单的从 spring 容器中读取到对象)
//    @Resource
    private UserService userService;

    public void sayHi(){
        System.out.println("do UserController sayHi()");
        userService.sayHi();
    }

}

2.2 Setter 注入

@Controller
public class UserController {

    //setter 注入
    private UserService userService;
    
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    
    public void sayHi(){
        System.out.println("do UserController sayHi()");
        userService.sayHi();
    }
}

2.3 构造方法注入

在类的构造方法中实现注入:

@Controller
public class UserController {
    //构造方法注入     //可注入 final 修饰的不可变的对象
    private final UserService userService;
    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
    public void sayHi(){
        System.out.println("do UserController sayHi()");
        userService.sayHi();
    }
}

注意事项:
如果类中有多个构造方法,需要加上 @Autowired 来明确指定到底使用哪个构造方法,否则会报错。

四、Bean的作用域和生命周期

Bean 的作⽤域是指 Bean 在 Spring 整个框架中的某种⾏为模式,⽐如 singleton 单例作⽤域,就表示 Bean 在整个 Spring 中只有⼀份,它是全局共享的,那么当其他⼈修改了这个值之后,那么另⼀个⼈读取到的就是被修改的值。

1.Bean的作用域

1.1 Bean 的6种作用域      Spring 容器在初始化一个 Bean 的实例时,同时会指定该实例的作用域。

  1. singleton : 单例作用域

          该作用域下的 Bean 在 IoC 容器中只存在一个实例: 获取 Bean(通过 applicationContext.getBean等方法获取) 及装配 Bean (通过@Autowired注入) 都是对同一个 Bean。

  2. prototype : 原型作用域(多例作用域)

          每次对该作用域下的 Bean 的请求都会创建新的实例: 获取 Bean 及装配 Bean 都是新的对象实例。

  3. request : 请求作用域

          每次http请求会创建新的Bean实例,类似于prototype

  4. session : 会话作用域

          在⼀个http session中,定义⼀个Bean实例

  5. application : 全局作用域

          在⼀个http servlet Context中,定义⼀个Bean实例

  6. websocket : HTTP WebSocket 作用域

          在⼀个HTTP WebSocket的⽣命周期中,定义⼀个Bean实例。

注意 后 4 种状态是 Spring MVC 中的值,在普通的 Spring 项目中只有前两种。

1.2 设置作用域

声明 Bean 对象的作用域 使用 @Scope 标签:
@Scope 有两种婆娘个设置方式:

  1. 直接设置值:@Scope(“prototype”)
  2. 使用枚举设置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Component
public class UserBeans {
//    @Scope("prototype")  //原型作用域
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @Bean
    public User user(){
        User user=new User();
        user.setId(1);
        user.setName("张三");
        return user;
    }
}

2.Spring 的执行流程

(1)创建容器

(2)加载 xml配置文件 (以包扫描的方式)

(3)将Bean注册到 Spring 容器中,base-package 下,且带 Spring 注解的类。

         @Controller @Service @Component @Repository @Configuration
         带@Bean 的方法也会执行,方法的返回值注册到容器中。

(4)装配 Bean 属性,也叫依赖注入。
        如果 Bean 对象需要其他 Bean 对象作为属性,可以使用注解 @Autowired @Resource

Spring 执行流程:启动 Spring 容器 -> 实例化 Bean(分配内存空间) -> Bean 注册到 Spring 中(存操作)-> 将 Bean 装配到需要的类中。

3.Bean的生命周期

Bean的生命周期分为一下 5 大部分:

  1. 实例化 Bean(通过反射创建对象,为 Bean 分配内存空间)
  2. 设置属性 (Bean 的注入和装配)
  3. Bean 初始化
    • 实现各种 Aware 通知的接口方法;
    • 初始化前置方法
    • 初始化方法【两种实现方式:xml 方式、注解方式】
    • 初始化后置方法
  4. 使用 Bean
  5. 销毁 Bean
    销毁容器的各种方法: @PreDestory、DisposableBean接口方法、destroy-method。

以上就是今天总结的内容。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值