Java之Spring

2023-11-19


IOC优点:实现代码的解耦,对象(Bean)生命周期交给Ioc框架维护,作为程序员无需在关注了。
spring Ioc容器的最核心的功能:
(1)将Bean(对象)存储到spring(容器)中
(2)将Bean(对象)从spring(容器)中取出来

DI【依赖注入】和Ioc【控制反转】的区别
(1)Ioc是一种思想,而DI是一种实现
比如:想去吃饭,就是思想,而去吃了海底捞就是实现。

创建spring项目

(1)先创建一个maven项目
在这里插入图片描述
在这里插入图片描述

(2)添加spring框架支持(spring-context / spring-beans)
在pom.xml中添加如下代码

<dependencies>
   <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
  
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
</dependencies>

设置国内源:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

如果此目录下没有相应的settings.xml文件,把相应的文件拷贝进来。

(3)创建一个启动类并添加main
在这里插入图片描述
创建一个类。类名可以任意取。
在这里插入图片描述

执行结果:
在这里插入图片描述

存储bean对象到容器(spring)中

(1)先在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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
    
</beans>

将上述代码片段放置到创建的xml中【配置文件的名字可以任意取,此处取的是spring-config.xml】

(2)创建bean对象
在Java中就是普通的对象。
创建一个User对象

package com.beans;

public class User {
    public void sayHi(String name) {
        System.out.println("你好:"+name);
    }
}

(3)在配置文件中将需要保持到spring中的对象进行注册。
将bean通过配置文件注册到spring中。
在这里插入图片描述

从spring中将bean取出

(1)先得到spring上下文对象

 // 1. 得到spring上下文对象
        ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");

在这里插入图片描述

(2)通过上下文对象提供的getBean方法获取自己需要使用的bean对象

//2. 根据上下文对象提供的方法获取到bean
        User user=(User) context.getBean("user");

在这里插入图片描述

(3)使用bean对象【可选步骤】

//3.使用bean
        user.sayHi("李四");

除了 ApplicationContext 之外,我们还可以使⽤ BeanFactory 来作为 Spring 的上下⽂。

//另一种方法
        //1.得到bean工厂
        BeanFactory factory=new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
        // 2. 获取bean
        User user=(User) factory.getBean("user");
        //3.使用bean
        user.sayHi("张三");

ApplicationContext和 BeanFactory的区别?
相同点:都可以实现从容器中获取bean,都提供了getBean的方法。
不同点:

  1. ApplicationContext属于BeanFactory的子类。BeanFactory只是提供了基础访问bean的方法,而 ApplicationContext除了拥有BeanFactory所有功能之外,还提供了更多的方法实现,比如对国际化的支持。
  2. 从性能方面来说二者是不同的,BeanFactory是按需加载bean,ApplicationContext是饿汉方式,在创建时会将所有的bean都加载起来,以备以后使用。

getBean的更多用法:
(1)使用bean name获取bean

User user=(User) context.getBean("user");

(2)根据bean type 获取bean

User user= context.getBean(User.class);

此方法写法简单,但容易出问题。当同一个类型被注入到spring中多次的时候,就会报错。

(3)根据bean name和类型获取bean

 User user=context.getBean("user",User.class);

更简单的读取存储对象

在 Spring 中想要更简单的存储和读取对象的核⼼是使⽤注解。

存储bean对象

前置准备

在spring配置文件中设置bean扫描根路径
在resource下创建spring-config.xml,将下述代码写入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=""></content:component-scan>
</beans>

在这里插入图片描述

添加注解存储 Bean 对象

想要将对象存储在 Spring 中,有两种注解类型可以实现:

  1. 类注解:@Controller【控制器】、@Service【服务】、@Repository【仓库】、@Component【组件】、@Configuration【配置】。

为什么需要5大类注解?
让代码的可读性提高,让程序员能够直观的判断当前类的用途。
在这里插入图片描述
5大类注解之间有何关系
@Controller【控制器】、@Service【服务】、@Repository【仓库】、@Configuration都是基于@Component【组件】实现的,所以@Component【组件】可以认为是其他4个注解的父类。
在这里插入图片描述

关于bean name的规则:
如果类名是大驼峰,则bean name使用小驼峰,如果类名的第一个和第二个字母是大写的,则bean name是原类名。

  1. ⽅法注解:@Bean
    在 Spring 框架的设计中,⽅法注解 @Bean 要配合类注解才能将对象正常的存储到 Spring 容器中
    在这里插入图片描述
@Component
public class UserBeans {
    @Bean//注:只使用一个bean注解是无法将对象存储到容器中
    public User user1(){
        User user=new User();
        user.setId(1);
        user.setName("张丹");
        return user;

    }

}

bean命名规则:当没有设置name属性时,那么bean默认的名称就是方法名,当设置了那么属性后,只能通过重命名的name属性对应的值类获取,也就是说重命名之后,在使用方法名就获取不到bean对象。

获取bean对象

获取 bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注⼊。
对象装配(对象注⼊)的实现⽅法以下 3 种:

  1. 属性注⼊
@Controller
public class UserController2 {
    //对象注入方式1: 属性注入
    @Autowired
    private UserService userService;
    public void sayHi() {
        userService.sayHi();
    }


}

//属性注入
        UserController2 userController2=context.getBean(UserController2.class);
        userController2.sayHi();

  1. 构造⽅法注⼊
//使用构造方式实现bean注入(官方推荐)
@Controller
public class UserController3 {
    private  UserService userService;

    @Autowired
    public UserController3(UserService userService) {
        this.userService=userService;

    }
    public  void sayHi(){
        userService.sayHi();
    }
}
//构造方法注入
      UserController3 userController3=context.getBean(UserController3.class);
      userController3.sayHi();
  1. Setter 注⼊
@Controller
public class UserController4 {
    private UserService userService;
     @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public  void sayHi() {
         userService.sayHi();
    }

}
//setter注入
        UserController4 userController4=context.getBean(UserController4.class);
        userController4.sayHi();

属性注入、构造方法注入、setter注入的区别是什么?

  1. 属性注入特点:写法简单,但是通用性不好,它只能运行在Ioc容器下,如果是非Ioc容器就会出现问题。
  2. setter注入:早期spring版本推荐的写法。setter注入通用性没有构造方法注入通用。
  3. 构造方法注入:通用性更好。它能确保在使用注入对象之前,此注入对象一定初始化过了。当构造方法注入参数过多时,此时开发者就要检查自己写的代码是否符合单一设计原则的规范了,此注入 方式也是spring后期版本中推荐的注入方式。

另一种注入注解:@Resource
注:@Resource支持属性注入和setter注入,但不支持构造方法注入。

@Resource 和 @Autowired的区别?
都可以实现将对象注入到当前类当中。

  1. @Resource来自于JDK, @Autowired是spring框架提供的。
  2. 用法不同: @Autowired支持属性注入、构造方法注入和setter注入,而@Resource不支持构造方法注入。
  3. 支持的参数不同: @Resource支持更多的参数设置,比如name、type,而@Autowired只支持一种。

bean作用域和生命周期

定义

bean的作用域:bean在spring整个框架中的某种行为。

bean的6种作用域

  1. singleton:单例模式(默认)
  2. prototype:原型模式(多例模式)
  3. request:请求模式(适用于spring MVC)
  4. session:会话作用域(spring MVC)【一个会话共享一个对象】
  5. application:全局作用域(spring MVC)
  6. websocket:HTTP WebSocket作用域(spring WebSocket)

bean生命周期

  1. 实例化bean(为bean分配内存空间)
  2. 设置属性(对象注入)
  3. 初始化
    (1)执行各种通知
    (2)执行初始化前置方法
    (3)执行构造方法,有两种方式,一是执行@PostConstruct,另一种是init-method
    (4)执行初始化的后置方法
  4. 使用bean
  5. 销毁bean
    (1)@PreDestroy
    (2)重写DisposableBean接口方法
    (3)destroy-method
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java之Spring 的相关文章

  • 动态选择端口号?

    在 Java 中 我需要获取端口号以在同一程序的多个实例之间进行通信 现在 我可以简单地选择一些固定的数字并使用它 但我想知道是否有一种方法可以动态选择端口号 这样我就不必打扰我的用户设置端口号 这是我的一个想法 其工作原理如下 有一个固定
  • 如何使用assertEquals 和 Epsilon 在 JUnit 中断言两个双精度数?

    不推荐使用双打的assertEquals 我发现应该使用带有Epsilon的形式 这是因为双打不可能100 严格 但无论如何我需要比较两个双打 预期结果和实际结果 但我不知道该怎么做 目前我的测试如下 Test public void te
  • 如何在 Spring 中禁用使用 @Component 注释创建 bean?

    我的项目中有一些用于重构逻辑的通用接口 它看起来大约是这样的 public interface RefactorAwareEntryPoint default boolean doRefactor if EventLogService wa
  • 谷歌应用程序引擎会话

    什么是java应用程序引擎 默认会话超时 如果我们将会话超时设置为非常非常长的时间 会不会产生不良影响 因为谷歌应用程序引擎会话默认情况下仅存储在数据存储中 就像facebook一样 每次访问该页面时 会话仍然永远存在 默认会话超时设置为
  • java.lang.IllegalStateException:应用程序 PagerAdapter 更改了适配器的内容,而没有调用 PagerAdapter#notifyDataSetChanged android

    我正在尝试使用静态类将值传递给视图 而不是使用意图 因为我必须传递大量数据 有时我会收到此错误 但无法找出主要原因是什么 Error java lang IllegalStateException The application s Pag
  • 从最终实体获取根证书和中间证书

    作为密码学的菜鸟 我每天都会偶然发现一些简单的事情 今天只是那些日子之一 我想用 bouncy castle 库验证 java 中的 smime 消息 我想我几乎已经弄清楚了 但此时的问题是 PKIXparameters 对象的构建 假设我
  • jdbc mysql loginTimeout 不起作用

    有人可以解释一下为什么下面的程序在 3 秒后超时 因为我将其设置为在 3 秒后超时 12秒 我特意关闭了mysql服务器来测试mysql服务器无法访问的这种场景 import java sql Connection import java
  • 像 Java 这样的静态类型语言中动态方法解析背后的原因是什么

    我对 Java 中引用变量的动态 静态类型和动态方法解析的概念有点困惑 考虑 public class Types Override public boolean equals Object obj System out println i
  • 如何对不同的参数类型使用相同的java方法?

    我的问题 我有 2 个已定义的记录 创建对象请求 更新对象请求 必须通过实用方法进行验证 由于这两个对象具有相同的字段 因此可以对这两种类型应用相同的验证方法 现在我只是使用两种方法进行重载 但它很冗长 public record Crea
  • logcat 中 mSecurityInputMethodService 为 null

    我写了一点android应显示智能手机当前位置 最后已知位置 的应用程序 尽管我复制了示例代码 并尝试了其他几种解决方案 但似乎每次都有相同的错误 我的应用程序由一个按钮组成 按下按钮应该log经度和纬度 但仅对数 mSecurityInp
  • 获取文件的总大小(以字节为单位)[重复]

    这个问题在这里已经有答案了 可能的重复 java 高效获取文件大小 https stackoverflow com questions 116574 java get file size efficiently 我有一个名为 filenam
  • java for windows 中的文件图标叠加

    我正在尝试像 Tortoise SVN 或 Dropbox 一样在文件和文件夹上实现图标叠加 我在网上查了很多资料 但没有找到Java的解决方案 Can anyone help me with this 很抱歉确认您的担忧 但这无法在 Ja
  • Cucumber 0.4.3 (cuke4duke) 与 java + maven gem 问题

    我最近开始为 Cucumber 安装一个示例项目 并尝试使用 maven java 运行它 我遵循了这个指南 http www goodercode com wp using cucumber tests with maven and ja
  • 我如何在java中读取二进制数据文件

    因此 我正在为学校做一个项目 我需要读取二进制数据文件并使用它来生成角色的统计数据 例如力量和智慧 它的设置是让前 8 位组成一个统计数据 我想知道执行此操作的实际语法是什么 是不是就像读文本文件一样 这样 File file new Fi
  • 使用反射覆盖最终静态字段是否有限制?

    在我的一些单元测试中 我在最终静态字段上的反射中遇到了奇怪的行为 下面是说明我的问题的示例 我有一个基本的 Singleton 类 其中包含一个 Integer public class BasicHolder private static
  • 在java中为组合框分配键

    我想添加一个JComboBox在 Swing 中这很简单 但我想为组合中的每个项目分配值 我有以下代码 JComboBox jc1 new JComboBox jc1 addItem a jc1 addItem b jc1 addItem
  • 如何将双精度/浮点四舍五入为二进制精度?

    我正在编写对浮点数执行计算的代码的测试 不出所料 结果很少是准确的 我想在计算结果和预期结果之间设置一个容差 我已经证实 在实践中 使用双精度 在对最后两位有效小数进行四舍五入后 结果始终是正确的 但是usually四舍五入最后一位小数后
  • CamcorderProfile.videoCodec 返回错误值

    根据docs https developer android com reference android media CamcorderProfile html 您可以使用CamcorderProfile获取设备默认视频编解码格式 然后将其
  • 使用 svn 1.8.x、subclise 1.10 的 m2e-subclipse 连接器在哪里?

    我读到 m2e 的生产商已经停止生产 svn 1 7 以外的任何版本的 m2e 连接器 Tigris 显然已经填补了维护 m2e subclipse 连接器的空缺 Q1 我的问题是 使用 svn 1 8 x 的 eclipse 更新 url
  • 如何防止在Spring Boot单元测试中执行import.sql

    我的类路径中有一个 import sql 文件 其中包含一些 INSERT 语句 当使用 profile devel 运行我的应用程序时 它的数据被加载到 postgres 数据库中 到目前为止一切正常 当使用测试配置文件执行测试时 imp

随机推荐