Spring的读取和存储对象

本文详细介绍了Spring如何存储和获取Bean对象,包括使用注解存储Bean,如@Controller、@Service等,以及通过@Autowired和@Resource进行属性和构造注入。同时,讨论了Bean的作用域,如singleton和prototype,并解析了Bean的生命周期,从实例化、属性设置到初始化和销毁的全过程。

一、存储Bean对象

第一步:配置扫描路径

首先要明确的是这一步是非常重要的。只有被配置的包下的所有类,添加了注解才能被正确的识别并保存到 Spring 中。

        //ApplicationContext是Spring容器的顶级接口
        //AnnotationConfigApplicationContext是其中一个实现类,
        // 作用:
        //  1. 扫描指定包路径下,使用Spring框架注解的类。
        //  2. 注册这些类到容器中=》框架帮助我们new对象,及注入队象依赖关系
        ApplicationContext context
                = new AnnotationConfigApplicationContext("org.example");

第二步:添加注解存储Bean对象

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

1. 类注解:@Controller、@Service、@Repository、@Component、@Configuration。

2. 方法注解:@Bean

我们还要认识的是:方法注解@Bean

这块要注意的是方法注解要配合类注解使用。如果我们单单使用Bean注解的话,要想获取Bean对象中的值,我们会发现获取不到。

二、获取Bean对象(装配/注入)

2.1 属性注入

属性注入是使用 @Autowired 实现的,将 Service 类注入到 Controller 类中
分层的依赖关系:51a7196990b7425b94a35f1ba2b832cd.png

 

 

package org.example.controller;

import lombok.Data;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
@Data// lombok注解:自动生成Getter、Setter、hashCode、equals、toString
public class UserController {

    //使用String容器,帮助我们将Bean容器中的
    @Autowired
    private UserService userService;

}
--------------------------------------------------------------------------------
package org.example.service;

import lombok.Data;
import org.example.mapper.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Data
public class UserService {

    @Autowired
    private UserRepository userRepository;

}
--------------------------------------------------------------------------------
package org.example.mapper;

import org.springframework.stereotype.Repository;

@Repository
public class UserRepository {

}

 2.2 构造注入

package org.example.service;

import lombok.Data;
import org.example.mapper.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Data
public class UserService {

//    @Autowired
    private UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

构造注入和属性注入是一样的。本质是将UserService注册到容器中。

DI依赖注入,有两种实现方式:属性注入和构造注入。

2.3 @Resource:另一种注入关键字

1. @Autowried 和 @Resource实现的效果是一样的。

@Autowired 和 @Resource 的区别:

  1. 出身不同:@Autowired 来自于 Spring,而 @Resource 来自于 JDK 的注解;
  2. 使用时设置的参数不同:相比于 @Autowired 来说,@Resource 支持更多的参数设置,例如name 设置,根据名称获取 Bean。
一个类型,多个bean注入的方式
    //1. 使用变量名
    @Autowired
    private Bean对象2 testBean2_1;
    //2. 使用注解
    @Autowired
    @Qualifier("testBean2_1")
    private  Bean对象2 bean对象2_1;

    // 3.
    @Resource(name = "testBean2_2")
    private  Bean对象2 bean对象2_2;

 三、Bean的作用域

类注解:使用单例模式,注册到容器中;

方法注解:可与i注册一个类型,多种实例对象。

如果只有一个实例对象,在两个地方,希望有不同的属性;

解决方法:定义两个实例对象,分别拥有不同的属性,

方法注解:@Bean定义多个方法来注册同类型多个Bean实例;

类注解:就需要通过修改作用域来实现这个功能;

 这是就使用@Scope();

@Scope("singleton");//默认还是单例

bean1=org.example.model.Bean对象1@33aeca0b, bean2=org.example.model.Bean对象1@33aeca0b

@Scope("prototype");//每次对该作用域下的Bean的请求都会创建新的实例

bean1=org.example.model.Bean对象1@18cebaa5, bean2=org.example.model.Bean对象1@463b4ac8

四、Bean的生命周期

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

1.实例化 Bean(为 Bean 分配内存空间)
2.设置属性(Bean 注入和装配)
3.Bean 初始化

  • 实现了各种 Aware 通知的方法,如 BeanNameAware、BeanFactoryAware、ApplicationContextAware 的接口方法;
  • 执行 BeanPostProcessor 初始化前置方法;
  • 执行 @PostConstruct 初始化方法,依赖注入操作之后被执行;
  • 执行自己指定的 init-method 方法(如果有指定的话);
  • 执行 BeanPostProcessor 初始化后置方法。

4.使用 Bean
5.销毁 Bean

销毁bean的各种方法,如 @PreDestroy、DisposableBean 接口方法、destroy-method。


1,2,3步骤3完成,才算Bean注册成功。 

创建好对象;依赖注入(属性初始化);其他初始化内容;把Bean对象放入容器中。

步骤一类似于:new 对象

步骤二类似于:依赖注入:属性赋值

步骤三类似于:表示bean要初始化的内容很多,才能使用

实例化和初始化的区别

实例化和属性设置是 Java 级别的系统“事件”,其操作过程不可人工干预和修改;而初始化是给开发者提供的,可以在实例化之后,类加载完成之前进行自定义“事件”处理。

package org.lifecycle.model;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

//@Service
public class MyBean implements BeanNameAware,
        BeanFactoryAware,
        ApplicationContextAware,
        InitializingBean,
        DisposableBean {

    public MyBean() {
        System.out.println("Bean生命周期方法");
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("BeanNameAware接口生命周期方法");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryAware接口生命周期方法");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware接口生命周期方法");
    }

    @PostConstruct
    public void 初始化方法1() {
        System.out.println("Bean初始化方法:@PostConstruct");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Bean初始化方法:@Bean(initMethod=本方法名)");
    }

    public void 初始化方法2() {
        System.out.println("Bean初始化方法:InitializingBean");
    }
    @PreDestroy
    public void 销毁方法1() {
        System.out.println("Bean的销毁方法:@PreDestroy");
    }


    @Override
    public void destroy() throws Exception {
        System.out.println("Bean的销毁方法:DisposableBean");
    }

    public void 销毁方法2() {
        System.out.println("Bean的销毁方法:@Bean(initMethod=本方法名)");
    }
}
---------------------------------------------------------------------------------
package org.lifecycle.config;

import org.lifecycle.model.MyBean;
import org.omg.CORBA.PUBLIC_MEMBER;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class LifecycleConfig implements BeanPostProcessor {

    @Bean(initMethod = "初始化方法2",destroyMethod = "销毁方法2")
    public MyBean bean() {
        return new MyBean();
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor生命周期方法:初始化前置方法");
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor生命周期方法:初始化后置方法");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }


}
----------------------------------------------------------------------------------------
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context
                = new AnnotationConfigApplicationContext("org.lifecycle");

        context.close();
    }

执行结果:

Bean生命周期方法
BeanNameAware接口生命周期方法
BeanFactoryAware接口生命周期方法
ApplicationContextAware接口生命周期方法
BeanPostProcessor生命周期方法:初始化前置方法
Bean初始化方法:@PostConstruct
Bean初始化方法:@Bean(initMethod=本方法名)
Bean初始化方法:InitializingBean
BeanPostProcessor生命周期方法:初始化后置方法
12:15:38.792 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@e73f9ac, started on Wed Jul 20 12:15:38 CST 2022
Bean的销毁方法:@PreDestroy
Bean的销毁方法:DisposableBean
Bean的销毁方法:@Bean(initMethod=本方法名)

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值