Spring Bean注册与注入实现方法详解

目录
  • 1. 逻辑上的 Bean 注册
  • 2. XML 注册 Bean 到自建的库中
    • 2.1 工厂方法
    • 2.2 使用工厂方法和实例化工厂注册 Bean
  • 3. XML 配合注解进行 Bean 注册
  • 4. 使用注解注册 Bean
    • 4.1 注解方式注册的必要条件
    • 4.2 用到的注解
    • 4.3 @Component注解注入
    • 4.4 使用 @Bean 注解注册
  • 5. 通过注解注入 Bean
  • 6. 注入时的一个坑点
  • 7. 获取 库中的对象

上接【Spring】spring核心思想——IOC和DI

上篇文章结尾简单介绍了一下使用 XML 注册 Bean,这篇文章接着介绍一下 XML 注册 Bean 和使用注解注册、注入 Bean

1. 逻辑上的 Bean 注册

2. XML 注册 Bean 到自建的库中

上篇文章介绍了使用 XML 三种注册的三种方式 (直接注入、构造方法注入、set 方法注入),在这里继续介绍一下使用工厂方法 和 实例化工厂注册 Bean

2.1 工厂方法

工厂方法分为静态工厂方法和实例工厂方法

使用工厂方法注册就是调用静态工厂方法注册 Bean

实例化工厂注册就是调用实例工厂方法注册 Bean

2.2 使用工厂方法和实例化工厂注册 Bean

首先还是使用 XML 自建库,在 Main 方法中对库进行操作(这里对库的操作主要是打印 Bean)

import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Main {
    public static void main(String[] args) {
        FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("spring-config.xml");
        String[] names = context.getBeanDefinitionNames();
        for (String name : names) {
            Object bean = context.getBean(name);
            String canonicalName = bean.getClass().getCanonicalName();
            System.out.println(name + "     " + canonicalName);
        }
        int count = context.getBeanDefinitionCount();
        System.out.println("一共有 " + count + "个");
    }
}
<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--    通过工厂注册,bean 的实例化由工厂方法完成-->
    <bean id="工厂注册" class="com.hsq.ioc3.SomeClass" factory-method="createPerson"/>

<!--    通过已经注册的 bean 的实例方法注册,bean 的实例化由我们自己完成-->
    <bean id="工具bean" class="com.hsq.ioc3.SomeClass"/>
    <bean id="通过实例化工厂注册" factory-bean="工具bean" factory-method="instantCreatePerson"/>
</beans>
public class SomeClass {
    // 静态方法(可以直接通过类名调用)
    // 作用:返回一个对象
    // 这类方法被称为工厂方法
    public static Person createPerson() {
        System.out.println("createPerson 被调用");
        return new Person();
    }
    public Person instantCreatePerson() {
        System.out.println("instantCreatePerson 被调用");
        return new Person();
    }
}
public class Person {
    public Person() {
        System.out.println("Person 被调用");
    }
}

通过打印可以清楚的看到两种方法都成功注册 Person 对象

3. XML 配合注解进行 Bean 注册

自建 XML 库中的配置文件有所改变

用到的注解 @Component,此注解后边会讲到

<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
<!--    扫描这个包下的所有类,如果没在这个包下,即使加了注解接不会被注入-->
    <context:component-scan base-package="com.hsq.ioc3"/>
</beans>
import org.springframework.stereotype.Component;
@Component
public class World {
    public World() {
        System.out.println("World 被调用");
    }
}

通过打印可以清楚看到,World 对象被成功注册

4. 使用注解注册 Bean

使用注解注册简而言之就是使用某个注解修饰类或方法,对其进行注册

使用注解注册 Bean 是注册进 Spring 提供的库,就不需要自建库了

4.1 注解方式注册的必要条件

  • 要被注解修饰类
  • 被注册的 Bean 要在 XXXApplication 所在包下,否则注册不会成功

4.2 用到的注解

这几个注解在 IOC 场景下,没有区别,都是将类注册进 Spring 库,但在其他场景一般这样用

@Component:没有特殊作用时,都可以用

@Controller:SpringMVC中把此注解特殊化了,要求控制器类必须用此注解修饰

@Service:修饰中间数据整合的类

@Repository:修饰数据获取类

@Configuration:修饰配置类

4.3 @Component注解注入

import org.springframework.stereotype.Component;
@Component
public class World {
    public World() {
        System.out.println("World() 被调用");
    }
}
@SpringBootApplication
public class IocAApplication {
   public static void main(String[] args) {
      ConfigurableApplicationContext context = SpringApplication.run(IocAApplication.class, args);
      String[] names = context.getBeanDefinitionNames();
      System.out.println("bean 陈列如下:");
      for (String name : names) {
         Object bean = context.getBean(name);
         String canonicalName = bean.getClass().getCanonicalName();
         System.out.println(name + "   " + canonicalName);
      }
      int count = context.getBeanDefinitionCount();
      System.out.println("一共 " + count + "个");
   }
}

通过打印清楚看到,对象被注册

4.4 使用 @Bean 注解注册

使用 @Bean 修饰方法,@Configuration 修饰类

此方法注册就相当于 XML 中的工厂方法注册

@Configuration
public class AppConfig {
    // <bean id="hsq" factory-bean="appConfig" factory-method="hsq" />
    // 以工厂方法注册
    @Bean
    public String hsq() {
        return "hsq";
    }
    @Bean       // 这里的 World 由 Spring 注入
    // 因为 createHello 被 Spring 调用
    public Hello createHello(@Autowired World world) {
        System.out.println("createHello(), world = " + world);
        return new Hello(world);
    }
}

5. 通过注解注入 Bean

需要用到 World 类时

  • 先让 Hello 类被注册到 Spring 容器,并且实例化过程交给 Spring。———— @Component 修饰 Hello 类
  • 要求 World 类被注册到 Spring 中(类注册或者方法注册都可以)
  • 使用构造方法、set 方法、属性直接注入三种方法注入bean——使用 @Autowired 修饰
import org.springframework.stereotype.Component;
@Component
public class World {
    public World() {
        System.out.println("World() 被调用");
    }
}

构造方法注入

@Component
public class Hello {
    @Autowired      // 这个注解其实可以不写,但是建议写上,主要是让看代码的人知道我们的 World 对象是被注入的
                    // 如果有多个构造方法,告诉 Spring,实例化对象是,应该调用哪个
    public Hello(World world) {
        System.out.println("Hello(), world = " + world);
    }
}

set 方法注入

@Component
public class Hello2 {
    @Autowired          // 这里的此注解必须写上
    public void setWorld(World world) {
        System.out.println("setWorld(), World = " + world);
    }
}

属性直接注入

@Component
public class Hello3 {
    @Autowired
    public World world;     // world 属性的值会被 Spring 容器对象注入
    public void printWorld() {
        System.out.println("printWorld(), world = " + this.world);
    }
}

6. 注入时的一个坑点

当使用以下方法注入时,会注入进 NULL 值,而非对象,原因已在下面代码的注释中写出

// 发生在 set 注入 / 属性直接注入上
@Component
public class 注入时的一个坑点 {
    @Autowired
    public World world;
    public 注入时的一个坑点() {
        // 构造方法先执行,然后再进行注入(属性注入 / set 注入)
        // 所以,构造方法执行的时候,注入还没有发生,所以还是 null
        // 所以一般建议使用构造方法注入
        System.out.println("注入时的一个坑点(), world = " + this.world);
    }
}

7. 获取 库中的对象

ConfigurableApplicationContext context = SpringApplication.run(IocAApplication.class, args);
Object world1 = context.getBean("world");         // 根据 id 获取 bean
World world2 = context.getBean(World.class);         // 根据类型获取 bean
World world = context.getBean("world", World.class);      // 根据 id + 类型获取 bean

到此这篇关于Spring Bean注册与注入实现方法详解的文章就介绍到这了,更多相关Spring Bean注册与注入内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBean和Controller实现动态注册与注销过程详细讲解

    目录 说明 注册和注销工具类 编写测试用例 测试结果 注册Service 注册controller 注销Controller 部分场景下可能需要下载远程jar包,然后注册jar包中的Bean和Controller 说明 这里的Bean 一般特指 Service层的服务类,Controller本质上也是Bean 注册和注销工具类 这里用了一些 hutool的工具类,hutools是一个不错的基础工具集. package cn.guzt.utils; import cn.hutool.extra.s

  • SpringCloud注册中心部署Eureka流程详解

    目录 1.Eureka服务 2.服务提供者 3.服务消费者 4.服务调用测试 今天我们开始正式编码,如何创建spring boot项目这篇文章就不再讲述,如果想要了解可以阅读我之前的创建springboot项目. 首先我们先进行Spring cloud五大组件之一的注册中心,之前文章已经讲过注册中心的介绍,今天我们来部署Netflix的Eureka,进行单机部署以及高可用部署,并开发生产者以及消费者来进行测试eureka的注册消费.(ps:系列文章使用的Spring cloud版本为2021.0

  • SpringBoot注册FilterRegistrationBean相关情况讲解

    目录 思路 手动注册代码 思路 首先编写程序时,或多或少会存在几个固定的Filter,那么第一步就是为确定的那几个Filter指定好顺序.(通常情况下的使用场景是:你要将你现在编写的项目打包成jar给别的项目使用) 其次程序确定的几个Filter已经编写好了,那么需要将它们和不确定的那几个放在一起进行重新排序. 将排好序的Filter进行注册. 补充:FilterRegistrationBean的使用 @Bean FilterRegistrationBean<AFilter> filterRe

  • SpringBoot使用Spring Security实现登录注销功能

    1.首先看下我的项目结构 我们逐个讲解 /** * 用户登录配置类 * @author Administrator * */ public class AdminUserDateils implements UserDetails { private static final long serialVersionUID = -1546619839676530441L; private transient YCAdmin yCAdmin; public AdminUserDateils() { }

  • Spring Bean注册与注入实现方法详解

    目录 1. 逻辑上的 Bean 注册 2. XML 注册 Bean 到自建的库中 2.1 工厂方法 2.2 使用工厂方法和实例化工厂注册 Bean 3. XML 配合注解进行 Bean 注册 4. 使用注解注册 Bean 4.1 注解方式注册的必要条件 4.2 用到的注解 4.3 @Component注解注入 4.4 使用 @Bean 注解注册 5. 通过注解注入 Bean 6. 注入时的一个坑点 7. 获取 库中的对象 上接[Spring]spring核心思想——IOC和DI 上篇文章结尾简单

  • Spring中bean集合注入的方法详解

    目录 Map注入 List注入 Set注入 数组注入 应用 哈喽大家好啊,我是Hydra. Spring作为项目中不可缺少的底层框架,提供的最基础的功能就是bean的管理了.bean的注入相信大家都比较熟悉了,但是有几种不太常用到的集合注入方式,可能有的同学会不太了解,今天我们就通过实例看看它的使用. 首先,声明一个接口: public interface UserDao { String getName(); } 然后定义两个类来分别实现这个接口,并通过@Component注解把bean放入s

  • Spring利用注解整合Mybatis的方法详解

    目录 一.环境准备 步骤1:数据库相关 步骤2:导入jar包 步骤3:创建模型类 步骤4:创建Dao接口和实现类 步骤5:创建Service接口和实现类 步骤6:添加jdbc.properties文件 步骤7:添加Mybatis核心配置文件 步骤8:编写测试程序 二.整合思路分析 三.整合步骤 步骤1:导入整合jar包 步骤2:创建数据源配置类 步骤3:创建Mybatis配置类 步骤4:创建Spring主配置类 步骤5:编写运行程序 一.环境准备 步骤1:数据库相关 建库建表 创建spring_

  • Spring中自定义数据类型转换的方法详解

    目录 类型转换服务 实现Converter接口 实现ConverterFactory接口 实现GenericConverter接口 环境:Spring5.3.12.RELEASE. Spring 3引入了一个core.onvert包,提供一个通用类型转换系统.系统定义了一个SPI来实现类型转换逻辑,以及一个API来在运行时执行类型转换.在Spring容器中,可以使用这个系统作为PropertyEditor实现的替代,将外部化的bean属性值字符串转换为所需的属性类型.还可以在应用程序中需要类型转

  • Spring实现声明式事务的方法详解

    1.回顾事务 事务在项目开发过程非常重要,涉及到数据的一致性的问题,不容马虎! 事务管理是企业级应用程序开发中必备技术,用来确保数据的完整性和一致性. 事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用. 事务四个属性ACID 原子性(atomicity) 事务是原子性操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起作用. 一致性(consistency) 一旦所有事务动作完成,事务就要被提交.数据和资源处于一种满足业务规则的一致性状态中.

  • Spring Boot 控制层之参数传递方法详解

    当然,您自己创建一个项目也是可以的. bean包下的Student.java package com.example.demo.bean; public class Student { private Integer id; //学号 private String name; //姓名 public Student() { } public Student(Integer id, String name) { this.id = id; this.name = name; } public In

  • Spring Boot读取resources目录文件方法详解

    这篇文章主要介绍了Spring Boot读取resources目录文件方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在Java编码过程中,我们常常希望读取项目内的配置文件,按照Maven的习惯,这些文件一般放在项目的src/main/resources下,因此,合同协议PDF模板.Excel格式的统计报表等模板的存放位置是resources/template/test.pdf,下面提供两种读取方式,它们分别在windows和Linux

  • Spring Boot自定义错误视图的方法详解

    Spring Boot缺省错误视图解析器 Web应用在处理请求的过程中发生错误是非常常见的情况,SpringBoot中为我们实现了一个错误视图解析器(DefaultErrorViewResolver).它基于一些常见的约定,尝试根据HTTP错误状态码解析出错误处理视图.它会在目录/error下针对提供的HTTP错误状态码搜索模板或者静态资源,比如,给定了HTTP状态码404,它会尝试搜索如下模板或者静态资源: /<templates>/error/404.<ext> - 这里<

  • Navicat Premium 15无限试用注册表修改的方法详解

    最近看上了Navicat Premium 15对PostgreSQL的支持,老版本的会有找不到oid字段报错,网上栖息的一些和谐版本是通过暴力修改二进制文件中的密钥来完成的,把可执行文件的数字签名也给破坏了,若遇到别有用心的捆绑个后门也不是不可以,运行着没有底气,于是寻找突破14天试用的办法. 网上有12版本的删注册表方法,显得有些暴力,本文在这些方法的基础上缩小了删除的范围,避免伤及无辜. 首先把HKEY_CURRENT_USER\Software\Classes\CLSID和HKEY_CUR

  • Spring Security动态权限的实现方法详解

    目录 1. 动态管理权限规则 1.1 数据库设计 1.2 实战 2. 测试 最近在做 TienChin 项目,用的是 RuoYi-Vue 脚手架,在这个脚手架中,访问某个接口需要什么权限,这个是在代码中硬编码的,具体怎么实现的,松哥下篇文章来和大家分析,有的小伙伴可能希望能让这个东西像 vhr 一样,可以在数据库中动态配置,因此这篇文章和小伙伴们简单介绍下 Spring Security 中的动态权限方案,以便于小伙伴们更好的理解 TienChin 项目中的权限方案. 1. 动态管理权限规则 通

随机推荐