Spring IoC(注解版)

453 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情。 在Spring容器的底层,最重要的功能就是IOC和DI,也就是控制反转和依赖注入。

  • IOC:控制反转,将类的对象的创建交给Spring类管理创建。\
  • DI:依赖注入,将类里面的属性在创建类的过程中给属性赋值。\
  • DI和IOC的关系:DI不能单独存在,DI需要在IOC的基础上来完成。

在Spring内部,所有的组件都会放到IOC容器中,组件之间的关系通过IOC容器来自动装配,也就是我们所说的依赖注入。接下来,我们就使用注解的方式来完成容器组件的注册、管理及依赖、注入等功能。


上述是官方的解释,通过上一篇的介绍,我个人的理解如下:

IoC:控制反转(个人理解:权利移交),让别人为我们提供服务,Java创建对象(生命周期)和初始化(DI)的步骤交给Spring容器管理,当我们加载容器的时候,容器就会帮我们进行实例化和初始化操作。


注解注入JavaBean

(1)构建Maven项目,引入Spring的基础环境依赖

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

image-20211106194523606.png

(2)创建JavaBean类

package com.hanpang.model;

public class Person {
    /**调用构造方法是创建对象的根本推荐*/
    public Person(){
        System.out.print(this.getClass().getSimpleName()+"初始化创建"+Math.random());
    }
}

(3)创建核心配置文件(JavaConfig)

package com.hanpang.config;

import com.hanpang.model.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//这是一个容器,容器是来管理Bean的生命周期的
@Configuration //相当于Spring的核心配置XML
public class SpringAnnotationConfig {
    @Bean
    public Person person01(){
        return new Person();
    }
}

通过SpringAnnotationConfig类我们就能够将Person类注入到Spring的IOC容器中,很简单吧?主要我们在类上加上@Configuration注解,并在方法上加上@Bean注解,就能够将方法中创建的JavaBean注入到Spring的IoC容器中。

(4)获取Bean对象使用

package com.spring.text;

import com.hanpang.config.SpringAnnotationConfig;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringTest {

    //如何来加载Spring的注解驱动容器
    @Test
    public void loadSpringConfig(){
        //接口回调
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringAnnotationConfig.class);
        //1.通过类型来获取,因为我们知道容器中只有这一个类型
        Person p1 = context.getBean(Person.class);
        System.out.println(p1);
    }
}

(5)当容器中创建多个Person类型,如何获取对象呢?

package com.hanpang.config;

import com.hanpang.model.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//这是一个容器,容器是来管理Bean的生命周期的
@Configuration //相当于Spring的核心配置XML
public class SpringAnnotationConfig {
    @Bean
    public Person person01(){
        return new Person();
    }
    @Bean
    public Person person02(){
        return new Person();
    }
    @Bean("myperson03")
    public Person person03(){
        return new Person();
    }
}

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

Bean的默认名称为方法名称,可以可以通过value属性进行自定义,现在这样就不能使用类型来获取了,就必须使用唯一的值

public class SpringTest {

    //如何来加载Spring的注解驱动容器
    @Test
    public void loadSpringConfig(){
        //接口回调
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringAnnotationConfig.class);
        //如何获取容器已经创建好的对象,提供给我们使用
        //1.通过类型来获取,如果是相同的类,创建多次就不能使用按照类型获取
        //Person p1 = context.getBean(Person.class);
        //System.out.println(p1);
        //Person p2 = context.getBean(Person.class);
        //System.out.println(p2);
        //容器默认创建的对象是单例模式-static修饰
        //2.可以按照名称获取
        String[] names = context.getBeanNamesForType(Person.class);
        Arrays.stream(names).forEach(System.out::println);
        //默认情况下@Bean创建对象的默认名称为方法名称
        Person p1 = context.getBean("person01",Person.class);
        System.out.println(p1);
        Person p2 = (Person)context.getBean("person02");
        System.out.println(p2);
        Person p3 = (Person)context.getBean("myperson03");
        System.out.println(p3);

    }
}

结论:我们在使用注解方式向Spring的IOC容器中注入JavaBean时,如果没有在@Bean注解中明确指定bean的名称,就使用当前方法的名称来作为bean的名称;如果在@Bean注解中明确指定了bean的名称,则使用@Bean注解中指定的名称来作为bean的名称。