@Bean详解

本文详细介绍了Spring框架中`@Bean`注解的使用,包括指定Bean名称、初始化和销毁方法、作用域设定以及处理Bean间的依赖关系,帮助读者理解如何通过注解方式管理组件并实现依赖注入。

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


上文我们简单的通过注解类+@bean注解的方式将第三方类注入到了IOC容器进行管理,那么本文我们来详细介绍@bean的用法。

1. @Bean生成Bean的Name问题

@Bean注解源码:

public @interface Bean {
    //前两个注解可以指定Bean的标识
    @AliasFor("name")
    String[] value() default {};
    @AliasFor("value")
    String[] name() default {};
  
    //autowireCandidate 属性来指示该 Bean 是否候选用于自动装配。
    //autowireCandidate 属性默认值为 true,表示该 Bean 是一个默认的装配目标,
    //可被候选用于自动装配。如果将 autowireCandidate 属性设置为 false,则说明该 Bean 不是默认的装配目标,不会被候选用于自动装配。
    boolean autowireCandidate() default true;

    //指定初始化方法
    String initMethod() default "";
    //指定销毁方法
    String destroyMethod() default "(inferred)";
}

通过源码可以看到,我们可以通过name或者value来为组件进行赋值。

指定@Bean的名称:

@Configuration
public class AppConfig {

  @Bean("myThing") //指定名称
  public Thing thing() {
    return new Thing();
  }
}

@Bean 注释注释方法。使用此方法在指定为方法返回值的类型的 ApplicationContext 中注册 Bean 定义。缺省情况下,Bean 名称与方法名称相同。下面的示例演示 @Bean 方法声明:

@Configuration
public class AppConfig {

  @Bean
  public TransferServiceImpl transferService() {
    return new TransferServiceImpl();
  }
}

前面的配置完全等同于下面的Spring XML:

<beans>
  <bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>

2. @Bean 初始化和销毁方法指定

@Bean 注解支持指定任意初始化和销毁回调方法,非常类似于 Spring XML 在 bean 元素上的 init-methoddestroy-method 属性,如以下示例所示:

public class BeanOne {

  public void init() {
    // initialization logic
  }
}

public class BeanTwo {

  public void cleanup() {
    // destruction logic
  }
}

@Configuration
public class AppConfig {

  @Bean(initMethod = "init")
  public BeanOne beanOne() {
    return new BeanOne();
  }

  @Bean(destroyMethod = "cleanup")
  public BeanTwo beanTwo() {
    return new BeanTwo();
  }
}

3. @Bean Scope作用域

可以指定使用 @Bean 注释定义的 bean 应具有特定范围。您可以使用在 Bean 作用域部分中指定的任何标准作用域。singleton表示单例模式,prototype表示多例。

默认作用域为 singleton ,但您可以使用 @Scope 注释覆盖此范围,如以下示例所示:

@Configuration
public class MyConfiguration {

  @Bean
  @Scope("prototype")
  public Encryptor encryptor() {
    // ...
  }
}

4. @Bean方法之间依赖

4.1 场景说明

在实际应用场景中,我们可能需要在一个@bean方法中用到另一个bean组件,这样,bean方法之间就存在依赖关系。那么,如何处理这种依赖关系?

例如,当前有以下两个组件:

public class HappyMachine {
    
    private String machineName;
    
    public String getMachineName() {
        return machineName;
    }
    
    public void setMachineName(String machineName) {
        this.machineName = machineName;
    }
}
public class HappyComponent {
    //引用新组件
    private HappyMachine happyMachine;

    public HappyMachine getHappyMachine() {
        return happyMachine;
    }

    public void setHappyMachine(HappyMachine happyMachine) {
        this.happyMachine = happyMachine;
    }

    public void doWork() {
        System.out.println("HappyComponent.doWork");
    }

}

可以看到,HappyComponent 中包含HappyMachine 类型的属性,两者存在依赖关系。

4.2 方法一

直接调用方法返回 Bean 实例:在一个 @Bean 方法中直接调用其他 @Bean 方法来获取 Bean 实例,虽然是方法调用,也是通过IoC容器获取对应的Bean,例如:

@Configuration
public class JavaConfig {

    @Bean
    public HappyMachine happyMachine(){
        return new HappyMachine();
    }

    @Bean
    public HappyComponent happyComponent(){
        HappyComponent happyComponent = new HappyComponent();
        //直接调用方法即可! 
        happyComponent.setHappyMachine(happyMachine());
        return happyComponent;
    }

}

可以看到,先使用@Bean将happyMachine注入IOC容器,之后在happyComponent的bean方法中,可以调用happyMachine的bean方法即可。

4.3 方法二

参数引用法:通过方法参数传递 Bean 实例的引用来解决 Bean 实例之间的依赖关系,例如:


import com.atguigu.ioc.HappyComponent;
import com.atguigu.ioc.HappyMachine;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class JavaConfig {

    @Bean
    public HappyMachine happyMachine(){
        return new HappyMachine();
    }

   
    @Bean
    public HappyComponent happyComponent(HappyMachine happyMachine){
        HappyComponent happyComponent = new HappyComponent();
        //赋值
        happyComponent.setHappyMachine(happyMachine);
        return happyComponent;
    }

}

注意:

可以直接在形参列表接收IoC容器中的Bean!

  • 情况1: 如果只有一个bean,直接指定类型即可

  • 情况2: 如果有多个bean,(HappyMachine 名称 ) 形参名称等于要指定的bean名称。

    例如:

                    @Bean
                    public Foo foo1(){
                        return new Foo();
                    }
                    @Bean
                    public Foo foo2(){
                        return new Foo()
                    }
                    @Bean
                    public Component component(Foo foo1 / foo2 通过此处指定引入的bean)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值