Spring @Bean注解的使用场景与案例实现

 更新时间:2023年03月10日 08:59:02   作者:Super_Leng  
随着SpringBoot的流行,我们现在更多采用基于注解式的配置从而替换掉了基于XML的配置,所以本篇文章我们主要探讨基于注解的@Bean以及和其他注解的使用

一、简单介绍

翻看Spring的源码时,发现@Bean注解的源码上标注了Since: 3.0,也就是说,@Bean注解是Spring从3.0版本开始提供的源码。@Bean注解可以标注在方法上,将当前方法的返回值注入到IOC容器中,也可以标注到注解上,作为元注解使用。

二、注解说明

@Bean注解可以说是使用Spring开发应用程序时,使用的比较多的一个注解,尤其是基于SpringBoot开发应用程序时,@Bean注解使用的就很多了。@Bean注解可以标注到方法上,将当前方法的返回值注入到IOC容器中。@Bean注解也可以标注到注解上,作为元注解使用。

1. 注解源码

/**
 * @author Rod Johnson
 * @author Costin Leau
 * @author Chris Beams
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since 3.0
 */
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
 //Since: 4.3.3
 @AliasFor("name")
 String[] value() default {};
 @AliasFor("value")
 String[] name() default {};
    //Since: 5.1
 boolean autowireCandidate() default true;
 String initMethod() default "";
 String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;
}

从@Bean源码的注释可以看出,@Bean注解是Spring从3.0版本开始提供的注解,注解中各个属性的含义如下所示:

  • name:String[]数组类型,指定注入到IOC容器中的Bean的名称,可以指定多个名称。如果不指定name属性和value属性的值,则注入到IOC容器中的Bean的名称默认是方法的名称。
  • value:String[]数组类型,从Spring 4.3.3版本开始提供的@Bean的属性,作用与name属性相同。
  • autowireCandidate:boolean类型,表示是否支持自动按照类型注入到其他的Bean中。此属性会影响@Autowired注解,不会响应@Resource注解,默认为true,表示支持自动按照类型注入到其他的Bean中。
  • initMethod:指定初始化的方法。
  • destroyMethod:指定销毁的方法。

2. 注解使用场景

在使用Spring的注解开发应用程序时,如果是我们自己开发的类,可以在类上标注@Component注解(也可以是@Repository、@Service、@Controller等注解),将类注入到IOC容器中。但是,有时很多类不是我们自己写的,而是依赖的第三方的类库,此时就无法在类上标注@Component等注解了,此时就需要使用@Bean注解将其注入到IOC容器中。

也就是说,@Bean注解适用于将第三方提供的类注入到IOC容器中的场景。使用@Bean注解创建的Bean对象默认是单实例Bean对象。

三、使用案例

1. 案例描述

使用@Bean注解将User类的对象注入到IOC容器中,打印初始化和销毁方法,并验证使用@Bean注解创建的Bean对象默认是单实例Bean。

2. 案例实现

使用@Bean注解可以将类对象注入到IOC容器中,并且@Bean注解的initMethod属性可以指定初始化的方法,destroyMethod属性可以指定销毁的方法。当IOC容器对Bean对象进行初始化时,会执行@Bean注解的initMethod属性指定的方法,当IOC容器在关闭时,会执行@Bean注解的destroyMethod属性指定的方法,触发销毁方法的逻辑。

注意:上述逻辑仅限于注入到IOC容器中的单例Bean对象。如果是单实例Bean,则IOC容器启动时,就会创建Bean对象,IOC容器关闭时,销毁Bean对象。如果是多实例Bean,IOC容器在启动时,不会创建Bean对象,在每次从IOC容器中获取Bean对象时,都会创建新的Bean对象返回,IOC容器关闭时,也不会销毁对象。也就是说,如果是多实例Bean,IOC容器不会管理Bean对象。

本节,就以单实例Bean为例来实现案例程序,具体的实现步骤如下所示:

新建注入到IOC容器中的User类

public class User {
    private final Logger logger = LoggerFactory.getLogger(User.class);
    public User(){
        logger.info("执行构造方法...");
    }
    public void init(){
        logger.info("执行初始化方法...");
    }
    public void destroy(){
        logger.info("执行销毁方法...");
    }
}

IOC容器启动时,会创建User类的对象并调用init()方法进行初始化。IOC容器关闭时,会销毁User类的对象,并调用destroy()方法执行销毁逻辑。

可以看到,User类的实现比较简单,提供了一个无参构造方法,一个表示初始化的init()方法和一个表示销毁的destroy()方法,每个方法中都打印了相应的日志来说明调用了对应的方法。

创建Spring的配置类BeanConfig

@Configuration
@ComponentScan(basePackages = "com.lwk.demo.spring.annocation.bean")
public class BeanConfig {
    @Bean(initMethod = "init", destroyMethod = "destroy")
    public User user(){
        return new User();
    }
}

可以看到,在BeanConfig类上标注了@Configuration注解,说明BeanConfig类是一个Spring的配置类,并且在BeanConfig类上标注了@ComponentScan注解,指定要扫描的包为com.lwk.demo.spring.annocation.bean。

在BeanConfig类中定义了一个user()方法,返回一个User对象。在user()方法上标注了@Bean注解,并通过initMethod属性指定的初始化方法为User类的init()方法,通过destroyMethod属性指定的销毁方法为User类的destroy()方法。

创建案例测试类BeanTest

public class BeanTest {
    private static final Logger LOGGER = LoggerFactory.getLogger(BeanTest.class);
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
        LOGGER.info("IOC容器启动完成....");
        User user1 = context.getBean(User.class);
        User user2 = context.getBean(User.class);
        LOGGER.info("user1是否等于user2===>>>{}", (user1 == user2));
        context.close();
    }
}

可以看到,在BeanTest类中,通过BeanConfig配置类创建了IOC容器,从IOC容器中两次获取User对象,分别赋值给user1和user2,打印user1是否等于user2的日志,并关闭IOC容器。

3. 案例测试

运行BeanTest类的main()方法,输出的日志信息如下所示:

15:56:57.404 [main] INFO com.lwk.demo.spring.annocation.bean.entity.User - 执行构造方法...
15:56:57.405 [main] INFO com.lwk.demo.spring.annocation.bean.entity.User - 执行初始化方法...
15:56:57.431 [main] INFO com.lwk.demo.spring.annocation.bean.BeanTest - IOC容器启动完成....
15:56:57.432 [main] INFO com.lwk.demo.spring.annocation.bean.BeanTest - user1是否等于user2===>>>true
15:56:57.437 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@41975e01, started on Thu Mar 09 15:56:57 CST 2023
15:56:57.438 [main] INFO com.lwk.demo.spring.annocation.bean.entity.User - 执行销毁方法...

可以看到,IOC容器在启动时,就创建了User对象,并调用了@Bean注解的initMethod方法指定的初始化方法,IOC容器在关闭时,调用@Bean注解的destroyMethod属性指定的销毁方法。并且通过打印的user1是否等于user2的日志为true,可以说明使用@Bean注解默认创建的Bean对象是单实例Bean,每个类在IOC容器中只会存在一个单实例Bean对象。

到此这篇关于Spring @Bean注解的使用场景与案例实现的文章就介绍到这了,更多相关Spring @Bean注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java实现对excel文件的处理合并单元格的操作

    java实现对excel文件的处理合并单元格的操作

    这篇文章主要介绍了java实现对excel文件的处理合并单元格的操作,开头给大家介绍了依赖引入代码,表格操作的核心代码,代码超级简单,需要的朋友可以参考下
    2021-07-07
  • 详解Java线程池的使用及工作原理

    详解Java线程池的使用及工作原理

    在日常开发过程中总是以单线程的思维去编码,没有考虑到在多线程状态下的运行状况.由此引发的结果就是请求过多,应用无法响应.为了解决请求过多的问题,又衍生出了线程池的概念.本文记录了Java中线程池的使用及工作原理,需要的朋友可以参考下
    2021-05-05
  • Springboot整合Active消息队列

    Springboot整合Active消息队列

    这篇文章主要介绍了Springboot整合Active消息队列的步骤,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下
    2020-12-12
  • 利用maven命令指定配置文件打包springboot项目

    利用maven命令指定配置文件打包springboot项目

    这篇文章主要介绍了利用maven命令指定配置文件打包springboot项目,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • SpringBoot JMX的基本使用方式

    SpringBoot JMX的基本使用方式

    这篇文章主要介绍了SpringBoot JMX的基本使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • 浅谈对象与Map相互转化

    浅谈对象与Map相互转化

    这篇文章主要介绍了利用BeanMap进行对象与Map的相互转换,在文中列举了完整代码,需要的朋友可以参考下。
    2017-09-09
  • Java实现银行账户管理子系统

    Java实现银行账户管理子系统

    这篇文章主要为大家详细介绍了Java实现银行账户管理子系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • java web实现自动登录

    java web实现自动登录

    这篇文章主要为大家详细介绍了java web实现自动登录,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • Java Guava的使用技巧整理

    Java Guava的使用技巧整理

    Guava是Google发布的一个开源库,主要提供了一些在Java开发中非常有用的工具类和API,不管是工作还是学习都是非常值得我们去熟悉的,一起来看看吧
    2023-03-03
  • Java连接mysql数据库以及mysql驱动jar包下载和使用方法

    Java连接mysql数据库以及mysql驱动jar包下载和使用方法

    这篇文章主要给大家介绍了关于Java连接mysql数据库以及mysql驱动jar包下载和使用方法,MySQL是一款常用的关系型数据库,它的JDBC驱动程序使得我们可以通过Java程序连接MySQL数据库进行数据操作,需要的朋友可以参考下
    2023-11-11

最新评论