Spring之@Bean注解

server/2024/9/23 3:04:29/

1. 使用方式

1.1 @Configuration + @Bean

1.1.1 创建实体类 User
@Data
@NoArgsConstructor
public class User {private String name;public User(String name) {this.name = name;}
}
1.1.2 创建配置类 UserConfig
@Configuration
public class UserConfig {@Beanpublic User user() {return new User("anna");}
}
1.1.3 创建配置类 AppConfig
@ComponentScan("com.ys")
public class AppConfig {
}
1.1.4 创建启动类 Main
public class Main {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);}
}
1.1.5 运行 main 方法,查看运行结果

通过运行结果,得出结论:Spring 容器中存在类型为 User 的 bean 

1.2 接口默认方法

1.2.1 创建实体类 DefaultCarRedCar 以及接口 Car
public class DefaultCar implements Car {
}@Component
public class RedCar implements Car {
}public interface Car {@Beandefault DefaultCar defaultCar() {return new DefaultCar();}
}
1.2.1 运行 main 方法,查看运行结果

通过运行结果,得出结论:Spring 容器中存在类型为 DefaultCar 的 bean

1.3 其他

  • @Bean 标注的方法既可以是实例方法也可以是静态方法
  • 除了 @Configuration + @Bean 的组合使用,原则上 @Component + @Bean、@ManagedBean + @Bean 也是可以的,主要是 full 和 lite 的区别,相关博文:Spring之什么是配置类

2. @Bean 各属性作用

2.1 name、value

指定 beanName ,未指定则为方法名

2.1.1 修改 UserConfig
@Configuration
public class UserConfig {@Bean("anna")public User user() {return new User("anna");}
}
2.1.2 运行 main 方法,查看运行结果

通过运行结果,得出结论:如果指定了 name,则就不存在 beanName 为 user(方法名) 的 bean

2.2 autowire

注入模型(已过期)

2.2.1 修改实体类 User
@Data
@NoArgsConstructor
public class User {private String name;private RedCar redCar;public User(String name) {this.name = name;}}
2.2.2 修改 UserConfig
@Configuration
public class UserConfig {@Bean(name = "anna", autowire = Autowire.BY_TYPE)public User user() {return new User("anna");}
}
2.2.3 运行 main 方法,查看运行结果

通过运行结果,得出结论:User 有个内部属性 redCar,如果注入模式是 byType,即使没有 @Autowired 注解,也会自动注入进去

相关知识点:Spring之注入模型

2.3 autowireCandidate

当注入的依赖存在多个候选者,如果候选者的 autowireCandidate 属性为 false,则不加入候选

2.3.1 修改 UserConfig
@Configuration
public class UserConfig {@Bean(name = "anna", autowireCandidate = false)public User user1() {return new User("anna");}@Bean(name = "bob")public User user2() {return new User("bob");}
}
2.3.2 运行 main 方法,查看运行结果

通过运行结果,得出结论:Spring 容器中一共有两个类型的为 User 的 bean,默认情况下,context.getBean(User.class) 如果找到多个 bean 会抛出异常,但是其中一个 bean 相关的 BeanDefinition 的 autowireCandidate 属性为 false,则表示它不是一个候选者,因此不会抛出异常,只返回 name 为 bob 的 bean

2.4 initMethod、destroyMethod

2.4.1 给实体类 User 添加相关方法
@Data
@NoArgsConstructor
public class User {private String name;private RedCar redCar;public User(String name) {this.name = name;}public void userInit() {System.out.println("user init");}public void userDestroy() {System.out.println("user destroy");}
}
2.4.2 修改 UserConfig
@Configuration
public class UserConfig {@Bean(initMethod = "userInit", destroyMethod = "userDestroy")public User user() {return new User("anna");}}
2.4.3 运行 main 方法,查看运行结果

通过运行结果,得出结论:相应方法会在特定的生命周期执行

3. @Bean和其他注解搭配使用

3.1 @Lazy

3.1.1 修改 UserConfig
@Configuration
public class UserConfig {@Bean@Lazypublic User user() {return new User("anna");}}
3.1.2 运行 main 方法,查看运行结果

通过运行结果,得出结论:在 getBean 方法执行之前一共有 17 个 bean,方法执行之后有 18 个bean,即相关 bean 是懒加载的

3.2 @Primary

3.2.1 修改 UserConfig
@Configuration
public class UserConfig {@Bean@Primarypublic User user1() {return new User("anna");}@Beanpublic User user2() {return new User("bob");}}
3.2.2 运行 main 方法,查看运行结果

通过运行结果,得出结论:@Primary 注解和其 autowireCandidate 属性的功能类似,都是选择最优候选者

3.3 @DependsOn

3.3.1 修改 UserConfig
@Configuration
public class UserConfig {@Bean@DependsOn("user2")public User user1() {return new User("anna");}//    @Bean
//    public User user2() {
//        return new User("bob");
//    }}
3.3.2 运行 main 方法,查看运行结果

通过运行结果,得出结论:Spring 容器中必须存在指定 names 的 bean,否则会抛出异常


http://www.ppmy.cn/server/103372.html

相关文章

给SystemUI 状态栏设置图标黑名单

方法一、Android 系统UI:状态栏屏蔽特定图标不显示 在Android设备上,状态栏是用户界面的重要组成部分。它包含了各种系统图标,如电池、信号强度、时间等。有时候,我们可能希望屏蔽某个特定的图标,使其在状态栏中不显示…

Android View的事件分发机制

文章目录 1. 使View滑动1.1 View基本知识1.2 使用scrollTo/scrollBy1.3 使用动画来移动View1.4 修改layoutParams来移动View 2. View的弹性滑动2.1 Scroller2.2使用动画2. 3 使用延时策略 View的事件分发机制事件分发源码解析1.Activty事件分发的过程2.ViewGroup事件分发3.View…

【PB案例学习笔记】-33 PB连接Oracle数据库查询数据

大家好,我是晓凡。 写在前面 这是PB案例学习笔记系列文章的第33篇,该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习,提高编程技巧,以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码…

分布式ID-一窥雪花算法的原生实现问题与解决方案(CosId)

分布式ID-雪花算法的问题与方案(CosId) 基本原理 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url%E5%88%86%E5%B8%83%E5%BC%8FID-%E9%9B%AA%E8%8A%B1%E7%AE%9…

什么原因会导致websocket断连

在Web应用中,WebSocket是一种常用的通信协议,它允许服务器和客户端之间进行全双工通信。然而,有时候我们会遇到WebSocket连接断开的情况。以下是可能导致WebSocket连接断开的一些常见原因: 网络问题:WebSocketClient依…

【C++进阶学习】第十四弹——特殊类设计——探寻各种情况下类的应用

前言: C类是C很重要的一个部分,在很多应用场景中都发挥着十分重要的作用,今天我们来讲解几个特殊场景下类的应用 目录 一、特殊类:只能在栈/堆上创建对象 1. 只在栈上创建对象 2. 只在堆上创建对象 二、特殊类:不能…

iOS Forensics with Belkasoft

本课程专为需要在工作中处理 iOS 设备并希望增强知识并获得 iOS 获取和分析实践经验的数字取证调查员而设计。 您将学到什么? 如何使用 iOS 获取的基本和高级方法,例如基于 checkm8 和基于代理的获取 如何从云端获取 iOS 数据 如何分析 iOS 应用程序&…

RocketMQ源码分析

RocketMQ源码分析 目录 目录 RocketMQ源码分析 - 环境搭建 RocketMQ源码分析 - NameServer RocketMQ源码分析 - Producer RocketMQ源码分析 - 消息存储 RocketMQ源码分析 - Consumer