当前位置: 首页 > news >正文

Java学习-----Bean

        在 Spring 框架中,Bean 是核心概念之一,它贯穿了整个 Spring 应用的生命周期,是实现依赖注入(DI)和控制反转(IoC)的基础。理解 Bean 的原理、作用及使用特点,对于掌握 Spring 框架至关重要。

        Spring Bean 的本质是由 Spring IoC 容器管理的对象,它的创建、初始化、依赖注入及销毁等过程均由容器控制,而非通过传统的new关键字手动创建。其核心原理可概括为以下两点:​

1. 控制反转(IoC)机制​

        传统 Java 开发中,对象的创建和依赖关系维护由开发者手动控制,例如在 A 类中通过new B()创建 B 类实例。而在 Spring 中,对象的创建权被转移到 IoC 容器,开发者只需通过配置(注解或 XML)声明对象的类型和依赖关系,容器会根据配置自动实例化对象并注入依赖,这一过程称为 “控制反转”。​

2. 生命周期管理​

        Spring Bean 的生命周期完全由容器管理,从实例化到销毁会经历多个阶段,主要包括:​

(1)实例化:容器通过反射创建 Bean 的实例。​

(2)属性注入:将依赖的 Bean 注入到当前 Bean 中(依赖注入)。​

(3)初始化:执行自定义初始化逻辑(如@PostConstruct注解的方法或实现InitializingBean接口)。​

(4)使用:Bean 处于可用状态,供其他组件调用。​

(5)销毁:容器关闭时,执行自定义销毁逻辑(如@PreDestroy注解的方法或实现DisposableBean接口)。

        Bean 作为 Spring 框架的基础组件,在应用中承担着关键角色,其主要作用体现在以下几个方面:​

(1)集中管理对象生命周期:容器统一管理 Bean 的创建、初始化和销毁,避免了手动管理对象生命周期的繁琐,减少了重复代码。​

(2)实现依赖注入(DI):通过容器自动将依赖的 Bean 注入到目标对象中,降低了对象之间的耦合度,便于代码维护和扩展。​

(3)提供统一的配置方式:支持注解(如@Component)、XML 配置和 Java 配置类等多种方式定义 Bean,灵活适应不同开发场景。​

(4)集成 AOP 等 Spring 特性:Bean 是 AOP(面向切面编程)的基础载体,通过容器可以轻松为 Bean 添加事务管理、日志记录等横切关注点。

        其主要的优点如下;

(1)降低耦合度:通过依赖注入,对象之间无需硬编码依赖关系,而是由容器动态关联,便于模块拆分和独立测试。​

(2)提高代码复用性:Bean 由容器统一管理,可通过配置实现单例复用,避免重复创建对象造成的资源浪费。​

(3)简化开发流程:开发者无需关注对象的创建和依赖维护,专注于业务逻辑实现,提升开发效率。​

(4)支持多种生命周期回调:可通过初始化和销毁方法,在 Bean 的生命周期节点执行自定义逻辑(如资源加载、连接关闭)。​

        缺点​有:

(1)容器启动成本:Spring IoC 容器初始化时需要扫描、解析 Bean 定义并创建实例,对于包含大量 Bean 的应用,可能导致启动时间过长。​

(2)调试复杂度增加:Bean 的创建和依赖注入由容器自动完成,若出现依赖循环或配置错误,定位问题的难度比手动管理对象更高。​

(3)过度设计风险:对于简单应用,引入 Spring Bean 可能导致不必要的复杂度,违背 “简单性优先” 的设计原则。​

(4)反射性能损耗:Bean 的实例化和属性注入依赖反射机制,虽然 JVM 对反射有优化,但在高频创建 Bean 的场景下,性能可能略低于直接调用构造方法。

// 定义一个Service层的Bean
@Service // 标注为服务层Bean,由Spring容器管理
public class UserService {// 依赖Dao层的Bean,通过@Autowired实现自动注入@Autowiredprivate UserDao userDao;// 业务方法:查询用户public User getUserById(Long id) {return userDao.selectById(id);}
}// 定义一个Dao层的Bean
@Repository // 标注为数据访问层Bean
public class UserDao {// 模拟数据库查询public User selectById(Long id) {return new User(id, "张三", 25); // 假设返回一个用户对象}
}// 启动类:扫描Bean所在的包
@SpringBootApplication(scanBasePackages = "com.example") // 扫描指定包下的Bean
public class SpringBeanDemoApplication {public static void main(String[] args) {// 启动Spring容器,返回ApplicationContext(IoC容器的顶层接口)ApplicationContext context = SpringApplication.run(SpringBeanDemoApplication.class, args);// 从容器中获取UserService的Bean实例UserService userService = context.getBean(UserService.class);// 调用Bean的方法User user = userService.getUserById(1L);System.out.println("查询到的用户:" + user);}
}
@Component
public class DataSourceBean {private Connection connection;// 初始化方法:在Bean创建后执行(替代XML中的init-method)@PostConstructpublic void init() {try {// 模拟创建数据库连接connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");System.out.println("数据库连接初始化成功");} catch (SQLException e) {throw new RuntimeException("初始化连接失败", e);}}// 业务方法:获取数据库连接public Connection getConnection() {return connection;}// 销毁方法:在Bean销毁前执行(替代XML中的destroy-method)@PreDestroypublic void destroy() {try {if (connection != null && !connection.isClosed()) {connection.close();System.out.println("数据库连接已关闭");}} catch (SQLException e) {e.printStackTrace();}}
}
// 配置类:替代XML配置文件
@Configuration
public class AppConfig {// 定义一个Bean,方法名即为Bean的名称(默认)@Beanpublic UserDao userDao() {return new UserDao(); // 手动创建UserDao实例,由Spring容器管理}// 定义依赖其他Bean的Bean@Beanpublic UserService userService() {UserService service = new UserService();service.setUserDao(userDao()); // 注入依赖的userDao Beanreturn service;}
}// 测试类
public class ConfigTest {public static void main(String[] args) {// 通过配置类启动Spring容器ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserService userService = context.getBean(UserService.class);System.out.println(userService.getUserById(2L));}
}

http://www.dtcms.com/a/292835.html

相关文章:

  • Datawhale AI 夏令营-心理健康Agent开发学习-Task1
  • 猎板 PCB:多场景适配下印制线路板的材料选择优化策略
  • 朴素贝叶斯算法原理与案例解析
  • linux: tar解压之后属主和属组不是当前用户问题
  • 2025人形机器人动捕技术研讨会即将于7月31日盛大开启
  • 阿里巴巴视觉算法面试30问全景精解
  • 知识库搭建之Meilisearch‘s 搜索引擎-创建搜索引擎项目 测评-东方仙盟测评师
  • 数据降噪/生物信号强化/缓解 dropout,深度学习模型 SUICA 实现空间转录组切片中任一位置基因表达的预测
  • [LLM]Synthetic Visual Genome
  • GNU到底是什么,与Unix和Linux是什么关系
  • 链表经典算法题
  • web复习
  • 网络原理 HTTP 和 HTTPS
  • kafka查看消息的具体内容 kafka-dump-log.sh
  • Python笔记完整版
  • 扇形区域拉普拉斯方程傅里叶解法2
  • 一款功能全面的文体场所预约小程序
  • Grails(Groovy)框架抛出NoHandlerFoundException而不是返回404 Not Found
  • 【多线程篇21】:深入浅出理解Java死锁
  • 《Uniapp-Vue 3-TS 实战开发》自定义预约时间段组件
  • 7.22总结mstp,vrrp
  • WebSocket心跳机制实现要点
  • 京东AI投资版图扩张:具身智能与GPU服务器重构科研新范式
  • 小鹏汽车视觉算法面试30问全景精解
  • 学习游戏制作记录(战斗系统简述以及击中效果)7.22
  • 为什么使用扩展坞会降低显示器的最大分辨率和刷新率
  • 智能泵房监控系统:物联网应用与智能管理解决方案
  • 【观察】维谛技术(Vertiv)“全链智算”:重构智算中心基础设施未来演进范式
  • 如何编译RustDesk(Unbuntu 和Android版本)
  • Cookies 详解及其与 Session 的协同工作