Spring中使用两种Aware接口自定义获取bean

本文介绍在Spring框架中如何根据Bean名称获取Bean对象,包括实现BeanFactoryAware和ApplicationContextAware接口的方法,并演示了如何在本地JUnit测试环境中通过ClassPathXmlApplicationContext获取Bean。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在使用spring编程时,常常会遇到想根据bean的名称来获取相应的bean对象,这时候,就可以通过实现BeanFactoryAware来满足需求,代码很简单:

复制代码
@Service
public class BeanFactoryHelper implements BeanFactoryAware { private static BeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } public static Object getBean(String beanName){
     if(beanFactory == null){
            throw new NullPointerException("BeanFactory is null!");
        }
     return beanFactory.getBean(beanName); 
  }
}
复制代码

  还有一种方式是实现ApplicationContextAware接口,代码也很简单:

复制代码
@Service
public class ApplicationContextHelper implements ApplicationContextAware {
    
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    
    public static Object getBean(String beanName){
        if(applicationContext == null){
            throw new NullPointerException("ApplicationContext is null!");
        }
        return applicationContext.getBean(beanName);
    }

}
复制代码

  上面两种方法,只有容器启动的时候,才会把BeanFactory和ApplicationContext注入到自定义的helper类中,如果在本地junit测试的时候,如果需要根据bean的名称获取bean对象,则可以通过ClassPathXmlApplicationContext来获取一个ApplicationContext,代码如下:

复制代码
  @Test
    public void test() throws SQLException {
        //通过从classpath中加载spring-mybatis.xml实现bean的获取
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-mybatis.xml");
        IUserService userService = (IUserService) context.getBean("userService");

        User user = new User();
        user.setName("test");
        user.setAge(20);
        userService.addUser(user);
    }
复制代码

 


### Spring Bean 生命周期详解 Spring 是一个轻量级的 Java 开发框架,其核心功能之一是对 Bean 的管理和控制。Bean 的生命周期是指从创建到销毁的过程,在这个过程中,Spring 容器会对 Bean 进行一系列的操作和管理。 #### 单例模式下的 Bean 生命周期 在 Spring 中,默认情况下,`singleton` 模式的 Bean 只会在容器启动时被实例化一次,并在整个应用运行期间保持唯一性[^1]。以下是 `singleton` 模式下 Bean 的典型生命周期: 1. **注册 BeanDefinition** 当 Spring 应用上下文启动时,它会解析所有的配置元数据(XML 文件、Java 注解或 Groovy 配置),并将这些信息转换为内部表示形式——`BeanDefinition` 对象[^3]。 2. **合并 BeanDefinition** 如果存在父类定义,则子类的 `BeanDefinition` 将与其父类的定义进行合并,形成最终的 Bean 定义。 3. **实例化前准备** 在实际实例化之前,Spring 会触发一些前置操作,例如通过 `InstantiationAwareBeanPostProcessor` 接口允许开发者自定义实例化的逻辑。 4. **实例化 Bean** Spring 容器根据指定的方式(构造函数或其他方式)来创建 Bean 实例。 5. **属性注入** 创建完成后,Spring 容器会根据配置文件或注解中的定义,将相应的属性值和依赖对象注入到该 Bean 实例中[^4]。 6. **Bean 后处理器处理** 在属性注入之后,Spring 提供了两种类型的后处理器接口: - `BeanPostProcessor`: 允许开发人员在初始化前后对 Bean 进行额外的定制。 - `InstantiationAwareBeanPostProcessor`: 能够更早介入 Bean 的生命周期,甚至可以在实例化阶段修改行为。 7. **执行 Aware 方法** 如果某个 Bean 实现了一些特定的 `Aware` 接口(如 `ApplicationContextAware`, `BeanNameAware` 等),那么 Spring 容器将会自动调用相应的方法并传入对应的资源。 8. **初始化前回调** 如果 Bean 实现了 `InitializingBean` 接口或者有 `<init-method>` 或者 `@PostConstruct` 标记的方法,Spring 容器将在初始化之前调用它们。 9. **初始化完成** 所有的初始化工作结束后,如果还实现了其他扩展点(如 AOP 动态代理生成等),也会在此阶段完成。 10. **销毁** 对于单例 Bean 来说,当 Spring 容器关闭时才会触发销毁过程;而对于原型作用域 (`prototype`) 下的 Bean,一旦脱离容器范围就不再受控,因此也不会主动销毁。 #### 原型模式下的 Bean 生命周期 与 `singleton` 不同的是,每次请求都会重新创建一个新的 Prototype Bean 实例给客户端使用,而不会对其进行缓存保存。这意味着它的整个生命期完全由外部环境决定而不是 Spring 自己负责跟踪维护。 ```java // 示例代码展示如何定义一个简单的 Bean 并设置其名称 @Configuration public class AppConfig { @Bean(name="myPrototypeBean", initMethod = "initialize", destroyMethod = "cleanup") @Scope("prototype") // 设置为原型作用域 public MyPrototypeBean myPrototypeBean(){ return new MyPrototypeBean(); } } class MyPrototypeBean implements InitializingBean, DisposableBean{ private String message; public void setMessage(String msg){ this.message=msg; } @Override public void afterPropertiesSet() throws Exception { System.out.println("Initializing Bean..."); } @Override public void destroy() throws Exception { System.out.println("Destroying Bean..."); } } ``` 上述例子展示了如何利用 XML 和注解混合的方式来声明一个具有复杂生命周期需求的对象。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值