软件编程
位置:首页>> 软件编程>> java编程>> Spring @Bean注解的使用场景与案例实现

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

作者:Super_Leng  发布时间:2023-11-20 04:44:22 

标签:Spring,@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对象。

来源:https://blog.csdn.net/qq_36602071/article/details/129424574

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com