Spring通过名称获取Bean示例


摘要:本文主要演示通过继承自抽象类ApplicationObjectSupport获取Bean实例。

参考文档:

  • Building a RESTful Web Service

提到共有以下几种方式:

  • 方法一:在初始化时保存ApplicationContext对象
  • 方法二:通过Spring提供的utils类获取ApplicationContext对象
  • 方法三:继承自抽象类ApplicationObjectSupport
  • 方法四:继承自抽象类WebApplicationObjectSupport
  • 方法五:实现接口ApplicationContextAware
  • 方法六:通过Spring提供的ContextLoader

完整示例代码请参考:https://github.com/sxpujs/spring-cloud-examples/tree/master/rest-service

软件环境:

  • 操作系统:MacOS Catalina 10.15.3
  • JDK 13.0.2
  • spring-boot-starter-parent: 2.2.5.RELEASE
  • Maven: 3.6.3

目录:

  • 文件布局
  • pom.xml
  • Task接口
    • Task实现类BarTask
    • Task实现类FooTask
  • Spring上下文工具类(继承ApplicationObjectSupport)
  • 用于测试的GreetingController
  • 测试

文件布局

localhost:rest-service didi$ tree .
.
├── pom.xml
├── src
│   └── main
│       └── java
│           └── com
│               └── example
│                   ├── RestServiceApplication.java
│                   ├── controller
│                   │   ├── Greeting.java
│                   │   └── GreetingController.java
│                   ├── service
│                   │   ├── BarTask.java
│                   │   ├── FooTask.java
│                   │   └── Task.java
│                   └── util
│                       └── SpringContextHolder.java

pom.xml

<?xml version="1.0" encoding="UTF-8"?>

    4.0.0
    
        com.example
        springcloud-parent
        1.0-SNAPSHOT
    
    com.example
    rest-service
    1.0-SNAPSHOT
    rest-service
    Demo project for Spring Boot

    
        13
    

    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


Task接口

文件路径:src/main/java/com/example/service/Task.java

package com.example.service;

public interface Task {
    void execute();
}

Task实现类BarTask

文件路径:src/main/java/com/example/service/BarTask.java

package com.example.service;

import org.springframework.stereotype.Service;

@Service("barTask")
public class BarTask implements Task {

    @Override
    public void execute() {
        System.out.println("Run BarTask");
    }

}

Task实现类FooTask

文件路径:src/main/java/com/example/service/FooTask.java

package com.example.service;

import org.springframework.stereotype.Service;

@Service("fooTask")
public class FooTask implements Task {

    @Override
    public void execute() {
        System.out.println("Run FooTask");
    }

}

Spring上下文工具类(继承ApplicationObjectSupport)

文件路径:src/main/java/com/example/util/SpringContextHolder.java

package com.example.util;

import com.example.service.Task;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.stereotype.Component;

@Component
public class SpringContextHolder extends ApplicationObjectSupport {

    public Task getTask(String beanName){
        return super.getApplicationContext().getBean(beanName , Task.class);
    }
}

用于测试的GreetingController

文件路径:src/main/java/com/example/controller/GreetingController.java

package com.example.controller;

import java.util.concurrent.atomic.AtomicLong;

import com.example.service.Task;
import com.example.util.SpringContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @Autowired
    SpringContextHolder holder;


    @GetMapping("/greeting")
    public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {

        Task task1 = holder.getTask("fooTask");
        Task task2 = holder.getTask("barTask");

        task1.execute();
        task2.execute();

        return new Greeting(counter.incrementAndGet(), String.format(template, name));
    }
}

其它如src/main/java/com/example/RestServiceApplication.java和src/main/java/com/example/controller/Greeting.java等文件请参考Github

测试

启动该服务后,在浏览器中输入:http://localhost:8080/greeting,会得到如下响应:

{"id":1,"content":"Hello, World!"}

在后台日志会看到:

Run FooTask
Run BarTask