• Spring的读取和存储对象


    一、存储Bean对象

    第一步:配置扫描路径

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

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

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

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

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

    2. 方法注解:@Bean

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

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

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

    2.1 属性注入

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

    1. package org.example.controller;
    2. import lombok.Data;
    3. import org.example.service.UserService;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.stereotype.Controller;
    6. @Controller
    7. @Data// lombok注解:自动生成Getter、Setter、hashCode、equals、toString
    8. public class UserController {
    9. //使用String容器,帮助我们将Bean容器中的
    10. @Autowired
    11. private UserService userService;
    12. }
    13. --------------------------------------------------------------------------------
    14. package org.example.service;
    15. import lombok.Data;
    16. import org.example.mapper.UserRepository;
    17. import org.springframework.beans.factory.annotation.Autowired;
    18. import org.springframework.stereotype.Service;
    19. @Service
    20. @Data
    21. public class UserService {
    22. @Autowired
    23. private UserRepository userRepository;
    24. }
    25. --------------------------------------------------------------------------------
    26. package org.example.mapper;
    27. import org.springframework.stereotype.Repository;
    28. @Repository
    29. public class UserRepository {
    30. }

     2.2 构造注入

    1. package org.example.service;
    2. import lombok.Data;
    3. import org.example.mapper.UserRepository;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.stereotype.Service;
    6. @Service
    7. @Data
    8. public class UserService {
    9. // @Autowired
    10. private UserRepository userRepository;
    11. @Autowired
    12. public UserService(UserRepository userRepository) {
    13. this.userRepository = userRepository;
    14. }
    15. }

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

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

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

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

    @Autowired 和 @Resource 的区别:

    1. 出身不同:@Autowired 来自于 Spring,而 @Resource 来自于 JDK 的注解;
    2. 使用时设置的参数不同:相比于 @Autowired 来说,@Resource 支持更多的参数设置,例如name 设置,根据名称获取 Bean。
    1. 一个类型,多个bean注入的方式
    2. //1. 使用变量名
    3. @Autowired
    4. private Bean对象2 testBean2_1;
    5. //2. 使用注解
    6. @Autowired
    7. @Qualifier("testBean2_1")
    8. private Bean对象2 bean对象2_1;
    9. // 3.
    10. @Resource(name = "testBean2_2")
    11. 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 级别的系统“事件”,其操作过程不可人工干预和修改;而初始化是给开发者提供的,可以在实例化之后,类加载完成之前进行自定义“事件”处理。

    1. package org.lifecycle.model;
    2. import org.springframework.beans.BeansException;
    3. import org.springframework.beans.factory.*;
    4. import org.springframework.context.ApplicationContext;
    5. import org.springframework.context.ApplicationContextAware;
    6. import org.springframework.stereotype.Service;
    7. import javax.annotation.PostConstruct;
    8. import javax.annotation.PreDestroy;
    9. //@Service
    10. public class MyBean implements BeanNameAware,
    11. BeanFactoryAware,
    12. ApplicationContextAware,
    13. InitializingBean,
    14. DisposableBean {
    15. public MyBean() {
    16. System.out.println("Bean生命周期方法");
    17. }
    18. @Override
    19. public void setBeanName(String s) {
    20. System.out.println("BeanNameAware接口生命周期方法");
    21. }
    22. @Override
    23. public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    24. System.out.println("BeanFactoryAware接口生命周期方法");
    25. }
    26. @Override
    27. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    28. System.out.println("ApplicationContextAware接口生命周期方法");
    29. }
    30. @PostConstruct
    31. public void 初始化方法1() {
    32. System.out.println("Bean初始化方法:@PostConstruct");
    33. }
    34. @Override
    35. public void afterPropertiesSet() throws Exception {
    36. System.out.println("Bean初始化方法:@Bean(initMethod=本方法名)");
    37. }
    38. public void 初始化方法2() {
    39. System.out.println("Bean初始化方法:InitializingBean");
    40. }
    41. @PreDestroy
    42. public void 销毁方法1() {
    43. System.out.println("Bean的销毁方法:@PreDestroy");
    44. }
    45. @Override
    46. public void destroy() throws Exception {
    47. System.out.println("Bean的销毁方法:DisposableBean");
    48. }
    49. public void 销毁方法2() {
    50. System.out.println("Bean的销毁方法:@Bean(initMethod=本方法名)");
    51. }
    52. }
    53. ---------------------------------------------------------------------------------
    54. package org.lifecycle.config;
    55. import org.lifecycle.model.MyBean;
    56. import org.omg.CORBA.PUBLIC_MEMBER;
    57. import org.springframework.beans.BeansException;
    58. import org.springframework.beans.factory.config.BeanPostProcessor;
    59. import org.springframework.context.annotation.Bean;
    60. import org.springframework.context.annotation.Configuration;
    61. @Configuration
    62. public class LifecycleConfig implements BeanPostProcessor {
    63. @Bean(initMethod = "初始化方法2",destroyMethod = "销毁方法2")
    64. public MyBean bean() {
    65. return new MyBean();
    66. }
    67. @Override
    68. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    69. System.out.println("BeanPostProcessor生命周期方法:初始化前置方法");
    70. return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    71. }
    72. @Override
    73. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    74. System.out.println("BeanPostProcessor生命周期方法:初始化后置方法");
    75. return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    76. }
    77. }
    78. ----------------------------------------------------------------------------------------
    79. public static void main(String[] args) {
    80. AnnotationConfigApplicationContext context
    81. = new AnnotationConfigApplicationContext("org.lifecycle");
    82. context.close();
    83. }

    执行结果:

    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=本方法名)

  • 相关阅读:
    LeetCode_贪心算法_困难_630.课程表 III
    红帽Linux的安装和部署
    Mac安装MySQL详细教程
    .Net服务器性能监控,应用耗时统一监控平台
    HDFS 伪分布式环境搭建
    采用ModelSim创建一个简单的实例
    【证明】若向量组线性相关,则向量组的线性映射也线性相关
    Met no ‘TRANSLATIONS’ entry in project
    杂想之一个C++内存泄露案例
    力扣每日一题(+日常水题|树型dp)
  • 原文地址:https://blog.csdn.net/TheDevice/article/details/125884607