javaee - Spring-02

本文介绍了Spring的核心概念,包括如何存取对象、依赖注入以及Bean的作用域和生命周期。存对象主要通过类注解、@Bean和@Configuration进行注册。取对象可以通过类型或名称获取。依赖注入使用@Autowired注解实现。Bean的作用域包括singleton和prototype等,影响其生命周期,而生命周期包括实例化、依赖注入和初始化、销毁等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring的使用核心

sprng就是一个容器,容器最重要的作用就是存放东西的的,而Spring就是一个存放类的容器,将类存进来并进行管理。因此在使用好Spring就需要关注两个重点,那就是如何将类放入到容器中,需要的时候如何取出来。
在这里插入图片描述

存对象(注册)

一:类注解
在类上使用注解 @Controller , @Service , @Repository , @Component 。需要保证该类会被Spring扫描到,这种定义方式默认会注册一个名称为类名首字母小写的Bean对象到容器中。
一、四个类注解的含义以及业务流程:
在这里插入图片描述
二、@Bean
当前类被 Spring 扫描到时,可以在方法上使用 @Bean 注解,通过方法返回类型,也可以定义、注册Bean对象,默认使用方法名作为Bean的名称。

@Bean
public User user1(){
    User user = new User();
    user.setUsername("abc");
    user.setPassword("123");
    return user; }
@Bean
public User user2(){
    User user = new User();
    user.setUsername("我不是汤神");
    user.setPassword("tang");
    return user; }

三、@Configuration
在类被Spring扫描到时,使用 @Configuration 注解,可以注册一个配置类到容器中。配置类一般用来自定义配置某些资源。

@Configuration
public class AppConfig {
}

lombok插件:
lombok 通过自定义的类注解,将自定义的类注解在程序编译的时候,转换成相应的JVM可以运行的代码来实现的。主要提供了@Getter、@Setter、@ToString、@Data等注解。@Getter对类里面的所有属性读取,给每一个属性生成一个原生的Get方法。’@Setter、@ToString类似。@Data注解包含了其他注解的功能,包括获得get,set等方法。

取对象

一、通过类型获取
这种获取方式要求该类型的Bean只能有一个实例,当有两个实例的时候,通过类名.class得到的都是同一个类,并不能知道想要获得哪一个实例。所以只能有一个实例

 //方法一、通过类型来获取
        LoginController loginController = 
        context.getBean(LoginController.class);
        System.out.println("方法一" + loginController);

二、通过名称获取
同一个类型的Bean可以有多个,需要注意的是,getBean里的字符串。当类名的第一个字母是大写第二个字母是小写的时候,需要将这个大写的字母变小写。当前两个字母都是大写的时候不需要变小写。


        //方法二、通过类名来获取,获取到的是object对象,所以这里需要强转
        LoginController loginController = 
        (LoginController)context.getBean("loginController") ;
        //loginController是类名的第一个字母小写得来的,有固定写法,与下面的方法三不一样
        System.out.println("方法二" + loginController);

三、通过类型字符串(实例的名字)加类型

 //方法二、通过类名来获取,获取到的是object对象,所以这里需要强转
        LoginController loginController = 
        (LoginController)context.getBean("loginController1"LoginController.class) ;
        //loginController1是LoginController类的一个实例对象的名字
        System.out.println("方法三" + loginController);

依赖注入

注入是从Spring 中取出某个对象,然后将这个取出来的对象赋值给具体类的属性引用,一般有属性注入,setter方法注入,属性注入。用@Autowired注解。
注册和注入的区别
注册是将这个类添加到容器中,让容器具有这个类(类的对象)。就比如我们上学时,班级的花名册一样,每个同学都应该将自己的姓名等信息进行登记,这样班级才会知道有哪些学生。有的时候,一个类的属性时类一个类的实例对象,而注入就是将容器里的类的实例取出来,赋值给该类的属性即可,这样我们就能直接用了。(实例化是容器中的,我们不用再进行new了,Spring帮我们创建了)。

属性注入
当前类被 Spring 扫描到时,可以在属性上使用 @Autowired 注解,会将容器中的Bean对象装配进来

 @Autowired
    private LoginRepository loginRepository;

在setter方法上使用 @Autowired 注解进行注入

private LoginService loginService ;
@Autowired
public void setLoginService(LoginService ls) {
this.loginService = ls;
}

其实只要写在方法上的 @Autowired 注解,都会将容器中的Bean对象注入方法参数,setter注入本质也是这样,只是setter方法一般都是设置属性用的,所以也归到属性注入。

构造方法注入:
当前类被 Spring 扫描到时,可以在构造方法上使用 @Autowired 注解,作用也是和setter方法类似,会将容器中的Bean对象注入方法参数。

@Service
public class LoginServiceByConstructor {
    private LoginRepository loginRepository;
    @Autowired
    public LoginServiceByConstructor(LoginRepository loginRepository){
        System.out.printf("LoginServiceByConstructor: %s%n", 
loginRepository);
        this.loginRepository = loginRepository;
   }
} 

注入指定的Bean:@Qualifier
同类型的Bean有多个时,注入该类型Bean需要指定Bean的名称:

  • 属性名或方法参数名设置为Bean的名称
  • 属性名或方法参数设置 @Qualifier(“名称”) 注解,注解内的字符串是Bean对象的名称
    以下 loginController 中定义了2个用户对象,且在方法参数中注入了Bean对象:
@Controller
public class LoginController {
    @Autowired
    private LoginService loginService;
    
    @Autowired
    @Qualifier("user1")
    private User u;
    
    @Autowired
    private User user2;
    
    @Bean
    public User user1(){
        User user = new User();
        user.setUsername("abc");
        user.setPassword("123");
        return user;
   }
    @Bean
    public User user2(){
        User user = new User();
        user.setUsername("张三");
        user.setPassword("tang");
        return user;
   }

Bean的作用域

Spring 容器在初始化一个 Bean 的实例时,同时会指定该实例的作用域。Spring有6个作用域,最后四种是基于Spring WebMVC生效:

//设置作用域
@Scope("singleton")
@Scope("prototype")

singleton
Spring IoC 容器中只会存在一个共享的 Bean 实例,无论有多少个Bean 引用它,始终指向同一对象。该模式在多线程下是不安全的(单例模式)。Singleton 作用域是Spring 中的缺省作用域(默认),也可以显示的将 Bean 定义为 singleton 模式,配置为:

通常无状态的Bean使用该作用域。无状态表示Bean对象的属性状态不需要更新。Spring默认选择该作用域
prototype
每次对该作用域下的Bean的请求都会创建新的实例。每个 Bean 实例都有自己的属性和状态,而 singleton 全局只有一个对象。根据经验,对有状态的bean使用prototype作用域,而对无状态的bean使用singleton。获取Bean(即通过applicationContext.getBean等方法获取)及装配Bean(即通过@Autowired注入)都是新的对象实例。

request
在一次 Http 请求中,容器会返回该 Bean 的同一实例。而对不同的 Http 请求则会产生新的 Bean,而且该 bean 仅在当前 Http Request 内有效,当前 Http 请求结束,该 bean实例也将会被销毁。
每次http请求会创建新的Bean实例,类似于prototype、一次http的请求和响应的共享、限定SpringMVC中使用
session
在一次 Http Session 中,容器会返回该 Bean 的同一实例。而对不同的 Session 请求则会创建新的实例,该 bean 实例仅在当前 Session 内有效。同 Http 请求相同,每一次session 请求创建新的实例,而不同的实例之间不共享属性,且实例仅在自己的 session请求内有效,请求结束,则实例将被销毁。
在一个http session中,定义一个Bean实例、用户回话的共享Bean, 比如:记录一个用户的登陆信息、限定SpringMVC中使用
application
在一个http servlet Context中,定义一个Bean实例Web应用的上下文信息,比如:记录一个应用的共享信息限定SpringMVC中使用
websocket
在一个HTTP WebSocket的生命周期中,定义一个Bean实例场景:WebSocket的每次会话中,保存了一个Map结构的头信息,将用来包裹客户端消息头。第一次初始化后,直到WebSocket结束都是同一个Bean。限定Spring WebSocket中使用。

Bean的生命周期

在这里插入图片描述
对于Bean的生命周期,主要步骤为:

  1. 实例化Bean:通过反射调用构造方法实例化对象。(将二进制流转化为类对象,由JVM完成
  2. 依赖注入:装配Bean的属性,也就是设置属性
  3. 实现了Aware接口的Bean,执行接口方法:如顺序执行BeanNameAware、BeanFactoryAware、ApplicationContextAware的接口方法。
  4. Bean对象初始化前,循环调用实现了BeanPostProcessor接口的预初始化方法
    (postProcessBeforeInitialization)
  5. Bean对象初始化:顺序执行@PostConstruct注解方法、InitializingBean接口方法、init-method方法(此时执行权属于程序,开始执行业务代码)
  6. Bean对象初始化后,循环调用实现了BeanPostProcessor接口的后初始化方法
    (postProcessAfterInitialization)
  7. 容器关闭时,执行Bean对象的销毁方法,顺序是:@PreDestroy注解方法、DisposableBean接口方法、destroy-method

补充说明:第一步的实例化是指new对象,Spring的语义中说初始化Bean包含Bean生命周期中的初始化步骤。

以下为核心步骤
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值