如何配置元数据?(如何使用Spring容器)

目录

一、引出问题(如何配置元数据?)

  • Java程序可以被简单理解为由bean组成的应用程序。
  • 有了Spring后,Spring会负责管理bean,并构建应用的上下文(IoC容器 / Spring容器)。
  • Spring怎么知道管理哪些bean呢?
    • 那当然是需要开发者提供信息(配置元数据)来告知Spring啊。
  • 如何配置元数据呢?(3种方式)【官方文档
    • (1)XML配置文件(xml配bean)
    • (2)基于注解的配置
    • (3)基于Java类的配置
  • 基于Spring的应用:

二、没有Spring的时代

  • 示例:
java 复制代码
public class Hello {
    public void sayHello() {
        System.out.println("Hello, World!");
    }
}

public class Application {
    public static void main(String[] args) {
        Hello hello = new Hello();
        hello.sayHello();
    }
}
  • 在使用bean之前,要自己创建,简单情况还好办。
  • 一旦类A中依赖类B,类B又依赖类C,这就麻烦了。
  • 还是把bean的控制权交给Spring吧(控制反转),让Spring来管理bean,并构建应用上下文。

三、XML配置文件(xml配bean)

1 格式

xml 复制代码
<?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 id="..." class="...">  
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions go here -->

</beans>

1.1 示例

xml 复制代码
<?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 id="hello" class="com.forrest.learnspring.springyes.xml.bean.Hello" />
</beans>

2 实例化一个Spring容器

java 复制代码
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
  • 常见的ApplicationContext的实现:
    • (1)ClassPathXmlApplicationContext
      • 从classpath中寻找beans.xml,并以该xml文件构建Spring容器。
    • (2)FileSystemXmlApplicationContext
      • 从文件系统中加载beans.xml文件,并以该xml文件构建Spring容器。
    • (3)AnnotationConfigApplicationContext
      • 根据注解和Java类构建Spring容器

3 使用Spring容器

java 复制代码
public class Application {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        Hello hello = applicationContext.getBean("hello", Hello.class);
        hello.sayHello();
    }
}

4 后言

  • 基于XML来配置元数据是非常强大的,官方文档也在这方面着墨甚多。
  • 然而,除非必须使用XML配置文件,否则Spring官方更推崇基于注解或Java类来配置元数据。

四、基于注解的配置 【1.9. Annotation-based Container Configuration

  • 没有了xml文件,Spring怎么知道要为哪些class创建bean?
  • 关键看:class有没有打上如下4个注解:
    • @Component
    • @Controller
    • @Service
    • @Repository

当然了,本质是@Component这个注解。例如:@Service这个注解也包含@Component。

  • Spring去哪找这些class呢?
    • 因此,还需要指定扫描组件的包。

1 示例1【applicationContext.scan("...")】

java 复制代码
@Component
public class Hello {
    public void sayHello() {
        System.out.println("Hello, World!");
    }
}

public class Application {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.scan("com.forrest.learnspring.springyes.annotation");
        applicationContext.refresh();
        Hello hello = applicationContext.getBean(Hello.class);
        hello.sayHello();
    }
}
  • 还可以再实例化AnnotationConfigApplicationContext时,指定扫描的包:
java 复制代码
public class Application {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext("com.forrest.learnspring.springyes.annotation.example2");
        Hello hello = applicationContext.getBean(Hello.class);
        hello.sayHello();
    }
}

2 示例2【通过注解来指定扫描的包】

java 复制代码
@ComponentScan("com.forrest.learnspring.springyes.annotation.example3")
public class Application {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Application.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        Arrays.stream(beanDefinitionNames).forEach(System.out::println);
    }
}

/**
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
application
hello
*/

五、基于Java类的配置

  • 这种本质是将基于xml的配置翻译为Java代码。

1 示例

java 复制代码
public class Hello {
    public void sayHello() {
        System.out.println("Hello, World!");
    }
}

@Configuration
public class HelloConfig {
    @Bean
    public Hello hello(){
        return new Hello();
    }
}

@ComponentScan("com.forrest.learnspring.springyes.config.example1")
public class Application {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Application.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        Arrays.stream(beanDefinitionNames).forEach(System.out::println);
    }
}

/**
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
application
helloConfig
hello
*/

六、Spring Boot时代

  • 为啥还要写AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Application.class);?这和业务逻辑又没有关系。
  • Spring Boot时代,就不用写了!详见:第一次开发基于SpringBoot的Java应用
java 复制代码
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
  • Spring Boot默认会扫描Application所在的包及其子包的所有bean。
  • Spring Boot整合Spring、Spring MVC、MyBatis,轻松搭建一个基于MVC架构的单体web应用。
    • 前端调用Http接口,后端的controller接收Http请求。
    • 核心业务逻辑由service层完成。
    • service层通过dao层获取数据库的数据进行处理。
相关推荐
Larcher8 分钟前
从“加载模型”界面到端侧推理:拆解一个 React + WebGPU 大模型 Demo
javascript·后端
极客先躯9 分钟前
高级java每日一道面试题-2026年05月03日-实战篇[Docker]-如何实现容器化环境的数据加密?
java·运维·docker·容器·金融·加解密·高级面试
xqqxqxxq39 分钟前
Java Socket 多人聊天室(私聊+群聊)技术笔记(V4版本)
java·网络·笔记
Larcher40 分钟前
从状态快照到惰性初始化:读懂 React useState 的三个关键场景
javascript·人工智能·后端
lazy H44 分钟前
Git clone 怎么用?克隆项目及常见问题完整教程
大数据·git·后端·学习·搜索引擎·github
wang09071 小时前
自己动手写一个spring之aop_1
java·后端·spring
神奇小汤圆1 小时前
IDEA 运行报 Command line is too long?别慌,两招搞定(附原理)
后端
SelectDB2 小时前
Apache Doris 4.1 全面增强 Iceberg:支持 UPDATE、MERGE INTO 与 Iceberg V3
后端
国科安芯2 小时前
FreeRTOS RISC-V 浮点上下文切换移植:在 IAR 工程中完整保存 FPU 寄存器
java·开发语言·单片机·嵌入式硬件·算法·系统架构·risc-v
Conan在掘金2 小时前
ArkTS 进阶之道(13):ForEach 循环渲染边界——为啥 build 里不能写 for 循环
后端