Spring IOC 注解进阶:@Bean 管理第三方 Bean,@Import 拆分配置,@Value 注入资源(Spring系列5)
在日常Spring开发中我们习惯用Component、Service、Repository这类注解标记自己编写的业务类让Spring自动扫描并纳入IOC容器管理。但如果是第三方Jar包中的类比如Druid数据源、第三方工具类我们无法修改源码添加注解这时候就需要用到Bean注解通过配置类灵活定义Bean。同时当项目规模扩大、Bean数量增多时我们还会遇到「配置类臃肿」「外部资源注入」「依赖其他Bean」等问题这就涉及到Import、Value、PropertySource等核心注解的实战应用。本文将从环境搭建到完整案例全面讲解这些注解的用法、原理、核心区别与最佳实践帮你彻底搞懂Spring第三方Bean管理的全流程。一、环境准备搭建基础Spring项目首先我们搭建一个基础的Spring项目为后续案例做准备1.1 创建Maven项目添加Spring依赖在pom.xml中引入Spring核心依赖dependencies dependency groupIdorg.springframework/groupId artifactIdspring-context/artifactId version5.2.10.RELEASE/version /dependency /dependencies1.2 创建基础类与配置类1. 配置类SpringConfigSpring的核心配置类Configuration public class SpringConfig { }2. BookDao接口与实现类模拟业务类public interface BookDao { void save(); }Repository public class BookDaoImpl implements BookDao { Override public void save() { System.out.println(book dao save ...); } }3. 运行类App启动Spring容器public class App { public static void main(String[] args) { AnnotationConfigApplicationContext ctx new AnnotationConfigApplicationContext(SpringConfig.class); } }1.3 最终项目结构spring_14_annotation_third_bean_manager ├── src │ ├── main │ │ ├── java │ │ │ └── com.itheima │ │ │ ├── config │ │ │ │ └── SpringConfig.java │ │ │ ├── dao │ │ │ │ ├── BookDao.java │ │ │ │ └── impl │ │ │ │ └── BookDaoImpl.java │ │ │ └── App.java │ │ └── resources └── pom.xml二、Bean注解管理第三方Bean以Druid数据源为例2.1 Bean的作用与核心特点Bean是Spring提供的、用于在配置类中手动定义Bean的注解核心作用是标记在Configuration配置类的方法上告诉Spring「这个方法返回的对象交给Spring容器管理作为一个Bean」。加了Bean后Spring会调用该方法将返回的对象存入IOC容器后续其他Bean需要该类型的对象时直接从容器中注入即可。2.2 Bean vs Component 核心区别对比很多同学会混淆Bean和Component这里用表格清晰对比两者的差异对比维度BeanComponent含Service/Repository等使用位置配置类Configuration修饰的方法上自定义类的类上创建逻辑完全自定义可手动new对象、设置属性、复杂初始化Spring自动扫描默认通过无参构造创建适用场景整合第三方库、需要复杂初始化逻辑的Bean自己编写的普通业务类控制粒度方法级可灵活控制Bean的创建过程类级统一扫描管理是否依赖源码不需要修改第三方类源码必须在类上添加注解依赖源码2.3 完整实现步骤我们以Druid数据源为例演示如何用Bean管理第三方Bean步骤1导入Druid依赖在pom.xml中添加Druid的Maven依赖dependency groupIdcom.alibaba/groupId artifactIddruid/artifactId version1.1.16/version /dependency步骤2在配置类中定义Bean方法在SpringConfig中添加方法返回DruidDataSource对象并添加Bean注解Configuration public class SpringConfig { Bean public DataSource dataSource(){ DruidDataSource ds new DruidDataSource(); ds.setDriverClassName(com.mysql.jdbc.Driver); ds.setUrl(jdbc:mysql://localhost:3306/spring_db); ds.setUsername(root); ds.setPassword(root); return ds; } }⚠️ 注意不能直接用DataSource ds new DruidDataSource()因为DataSource接口中没有对应的setter方法必须使用具体实现类DruidDataSource来设置属性。步骤3从IOC容器中获取Bean并测试修改App类从容器中获取DataSource对象并打印public class App { public static void main(String[] args) { AnnotationConfigApplicationContext ctx new AnnotationConfigApplicationContext(SpringConfig.class); DataSource dataSource ctx.getBean(DataSource.class); System.out.println(dataSource); } }运行程序控制台会打印Druid数据源对象说明第三方Bean已经成功被Spring管理。三、配置类拆分ComponentScan vs Import 两种方案如果把所有Bean都写在SpringConfig中会导致配置类越来越臃肿不利于代码阅读和分类管理。因此我们可以按业务类别拆分配置类比如把数据源相关的Bean放到JdbcConfig中。3.1 方案一ComponentScan包扫描引入不推荐实现步骤1. 创建JdbcConfig配置类添加Configuration和Bean注解Configuration public class JdbcConfig { Bean public DataSource dataSource(){ DruidDataSource ds new DruidDataSource(); ds.setDriverClassName(com.mysql.jdbc.Driver); ds.setUrl(jdbc:mysql://localhost:3306/spring_db); ds.setUsername(root); ds.setPassword(root); return ds; } }2. 在SpringConfig中添加包扫描扫描JdbcConfig所在的包Configuration ComponentScan(com.itheima.config) public class SpringConfig { }3. 运行App类依然可以正常获取DataSource对象。缺点无法直观看到Spring加载了哪些配置类、全量扫描增加容器负担不推荐生产环境使用3.2 方案二Import手动指定引入推荐Import是Spring提供的、用于手动指定需要加载的配置类的注解完美解决了包扫描的痛点。实现步骤1. 移除JdbcConfig的Configuration注解public class JdbcConfig { Bean public DataSource dataSource(){ DruidDataSource ds new DruidDataSource(); ds.setDriverClassName(com.mysql.jdbc.Driver); ds.setUrl(jdbc:mysql://localhost:3306/spring_db); ds.setUsername(root); ds.setPassword(root); return ds; } }2. 在SpringConfig中添加Import注解手动导入JdbcConfigConfiguration Import({JdbcConfig.class}) public class SpringConfig { }3.3 Import核心原理与使用场景本质Spring默认通过ComponentScan扫描带有Configuration、Component的类纳入容器管理。而Import的核心功能是强制指定类纳入Spring容器无论该类是否有Configuration或其他组件注解。核心使用场景导入第三方库中的配置类精细化控制配置加载避免全量扫描结合Conditional实现条件化导入配置3.4 Import使用注意事项参数是数组支持导入多个配置类Import({JdbcConfig.class, XxxConfig.class})一个配置类中只能写一次Import不能多次添加可以完全替代ComponentScan提升容器启动效率四、Bean方法中注入资源简单数据类型引用数据类型在使用Bean创建Bean时方法中往往需要依赖其他资源分为两类简单数据类型比如字符串、数字和引用数据类型比如其他Bean。4.1 简单数据类型注入ValuePropertySource读取配置文件需求分析将数据库连接四要素硬编码提取到properties文件通过注解注入。1. 在resources目录下创建jdbc.properties配置文件jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/spring_db jdbc.usernameroot jdbc.passwordroot2. 在JdbcConfig中添加PropertySource注解加载配置文件PropertySource(classpath:jdbc.properties) public class JdbcConfig { // 注入配置文件中的值 Value(${jdbc.driver}) private String driver; Value(${jdbc.url}) private String url; Value(${jdbc.username}) private String userName; Value(${jdbc.password}) private String password;Bean public DataSource dataSource(){ DruidDataSource ds new DruidDataSource(); ds.setDriverClassName(driver); ds.setUrl(url); ds.setUsername(userName); ds.setPassword(password); return ds; } }4.2 引用数据类型注入方法参数自动装配需求分析将BookDao对象注入到Bean方法中。1. 在SpringConfig中扫描BookDao所在的包Configuration ComponentScan(com.itheima.dao) Import({JdbcConfig.class}) public class SpringConfig { }2. 在JdbcConfig的dataSource方法中添加BookDao参数PropertySource(classpath:jdbc.properties)//这个注解建议放在主配置类SpringConfig上原因如下配置聚合主配置类是整个 Spring 环境的入口在这里统一管理所有配置扫描、导入、资源文件逻辑最完整。避免冗余如果以后还有其他配置类如 RedisConfig只需要在 SpringConfig里加一个PropertySource即可不需要每个配置类都写一遍。 public class JdbcConfig { Value(${jdbc.driver}) private String driver; Value(${jdbc.url}) private String url; Value(${jdbc.username}) private String userName; Value(${jdbc.password}) private String password;////不能在方法里定义BookDao bookDao用atuowired注解spring扫描不到。当 Bean 被初始化时Spring 会检查该 Bean 类的 类级别成员字段或 类级别的方法构造器、setter 等上的 Autowired并执行注入。 Bean public DataSource dataSource(BookDao bookDao){ System.out.println(bookDao); DruidDataSource ds new DruidDataSource(); ds.setDriverClassName(driver); ds.setUrl(url); ds.setUsername(userName); ds.setPassword(password); return ds; } }运行程序即可验证引用类型注入成功。五、总结与最佳实践核心知识点总结注解核心作用适用场景Bean在配置类方法上定义Bean管理第三方Bean、复杂初始化Import手动指定加载配置类拆分配置、导入第三方配置Value注入简单数据类型读取配置、注入常量PropertySource加载外部properties文件分离配置与代码最佳实践第三方Bean统一用Bean管理配置类按业务拆分用Import手动导入配置统一放到properties文件通过Value注入Bean方法依赖其他Bean时优先用方法参数注入减少ComponentScan范围提升容器启动效率
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2491235.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!