SpringBoot获取Bean

本文介绍了一种在Spring框架中获取容器内Bean的实用方法,通过实现ApplicationContextAware接口,可以方便地获取到单例或多例的Bean实例。并演示了如何通过Bean的名称或类型获取Bean,以及验证Bean的实例化模式。

一种最简单的方法是实现ApplicationContextAware类来获取容器中的bean:

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtil.applicationContext = applicationContext;
    }

    //获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //通过name获取 Bean.
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    //通过class获取Bean.
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

}

我们可以通过bean的名称、bean的类型或者bean的名称+类型来获取容器中的bean。

默认情况下,Spring容器中的bean是单例的,为此我做了一个测试,我创建了两个bean,一个是默认的,一个是我指定多例的:

import org.springframework.stereotype.Service;

/**
 * 这是一个单例的bean
 */
@Service
public class BeanSingletonService {
}
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

/**
 * 这是一个多例的bean
 */
@Service
@Scope("prototype")
public class BeanPrototypeService {
}

验证下我的想法:

import com.xqnode.learning.common.config.SpringContextUtil;
import com.xqnode.learning.service.BeanPrototypeService;
import com.xqnode.learning.service.BeanSingletonService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class LearningApplicationTests {
    
    @Test
    public void contextLoads() {
        BeanSingletonService s1 = SpringContextUtil.getBean(BeanSingletonService.class);
        BeanSingletonService s2 = SpringContextUtil.getBean(BeanSingletonService.class);
        BeanPrototypeService p1 = SpringContextUtil.getBean(BeanPrototypeService.class);
        BeanPrototypeService p2 = SpringContextUtil.getBean(BeanPrototypeService.class);
        System.out.println("s1==s2: " + s1.equals(s2));
        System.out.println("p1==p2: " + p1.equals(p2));
    }


}

bean
从结果中可以看到默认的BeanSingletonService 这个bean是单例的,两个对象完全相等,而我指定的BeanPrototypeService 这个bean则是多例的,两个bean不相同。

在Spring Boot应用程序中,获取Bean有多种方式。通常我们会依赖于Spring的上下文管理自动装配所需的组件,但在某些场景下也需要手动去取得某个特定的Bean实例。 ### 方式一:通过@Autowired注解 这是最常见的方式之一,在需要注入的地方直接使用`@Autowired`注解,并声明你要注入的对象类型即可让Spring自动为你找到并赋值相应的bean。 ```java @Service public class MyService { @Autowired private AnotherBean anotherBean; } ``` ### 方式二:利用构造函数或者Setter方法注入(@Inject/@Autowired) 除了字段级别的注入外,还可以选择将依赖项作为构造参数传入,或者是提供setter方法来设置依赖属性。这种方式有助于提高单元测试时的灵活性以及更清晰地表达出类之间的依赖关系。 #### 构造器注入示例: ```java @RestController public class MyController { private final AnotherBean bean; // 使用构造器注入另一个bean public MyController(AnotherBean bean) { this.bean = bean; } } ``` #### Setter方法注入示例: ```java @Component public class MyClass{ private Helper helper; @Autowired public void setHelper(Helper helper){ this.helper=helper; } } ``` ### 方式三:ApplicationContextAware 接口 如果是在非受管环境中想要访问到spring容器里的beans的话,则可以考虑实现 `org.springframework.context.ApplicationContextAware` 接口。这允许我们在任意地方获得整个application context 并从中检索指定名称Bean。 ```java import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component("myAppCtx") public class ApplicationContextProvider implements ApplicationContextAware { private static ApplicationContext ctx = null; public static ApplicationContext getApplicationContext() { return ctx; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { ctx = applicationContext; } } // 获取名为 "anotherBean" 的bean 示例: MyClass.anotherBeanInstance = (AnotherBean) ApplicationContextProvider.getApplicationContext().getBean("anotherBean"); ``` ### 方式四:从配置文件加载静态资源或者其他复杂类型的Beans 对于一些比较特殊的场景比如读取外部properties/json/yaml等格式的数据源生成对应的Bean对象,我们一般会采用工厂模式结合@Configuration + @Bean定义的方式来完成。 ```java @Configuration class AppConfig { @Value("${api.url}") String apiUrl; @Bean(name="httpClientConfiguredWithApiUrl") HttpClient createHttpClient(){ return HttpClient.createDefault(apiUrl); } } ``` 以上就是几种常见的在Spring Boot应用里获取、创建和注册Bean的方法了!
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员青戈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值