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

Java——注解开发模式下的 Spring IoC/DI 与 Bean 管理实战

在 B 站黑马程序员的 SSM 框架教程中,基于注解的开发模式是简化 Spring 配置、提升开发效率的核心实践。本文结合教程内容,系统解析注解驱动的 IoC(控制反转)、DI(依赖注入)及 Bean 管理,涵盖核心注解、实战技巧与企业级应用场景。

一、IoC 核心:注解声明 Bean 的三种方式

1. 基础注解:@Component 及其衍生注解​

通过注解替代 XML 中的标签,直接在类上声明 Bean,实现 “组件化”:

// 通用组件(推荐细化为专用注解)
@Component("userService") 
public class UserServiceImpl implements UserService { ... }// 业务层(语义更明确)
@Service("userService") 
public class UserServiceImpl implements UserService { ... }// 数据访问层(自动参与MyBatis整合)
@Repository("userDao") 
public class UserDaoImpl implements UserDao { ... }// Web层控制器(自动被SpringMVC扫描)
@Controller("userController") 
public class UserController { ... }

核心规则:​

  • value属性指定 Bean 的 id(可选,默认类名首字母小写)​
  • 需通过<context:component-scan base-package=“com”/>开启组件扫描

2. @Bean:手动定义 Bean(替代 XML 工厂方法)​

在@Configuration类中通过方法返回 Bean,适合第三方组件或复杂对象创建:

@Configuration
public class AppConfig {// 配置Druid数据源(替代XML的<bean>)@Bean("dataSource")public DataSource druidDataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");return dataSource;}// 整合MyBatis的SqlSessionFactory@Bean("sqlSessionFactory")public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {SqlSessionFactoryBean factory = new SqlSessionFactoryBean();factory.setDataSource(dataSource);return factory;}
}

适用场景:​

  • 第三方库组件(如 MyBatis、Redis 客户端)​
  • 需要编程式配置的 Bean(动态参数、条件判断)​

3. 条件化 Bean:@Conditional​

根据条件动态注册 Bean(如区分开发 / 生产环境):

// 开发环境启用本地缓存
@Conditional(DevEnvironmentCondition.class) 
@Bean("cacheManager")
public LocalCacheManager devCacheManager() { ... }// 生产环境启用分布式缓存
@Conditional(ProdEnvironmentCondition.class) 
@Bean("cacheManager")
public RedisCacheManager prodCacheManager() { ... }

二、DI 核心:依赖注入的三种注解方式​

1. 自动装配:@Autowired(byType 为主)​

(1)字段注入(最简洁,但违背 “构造器注入优先” 原则)

@Service
public class UserServiceImpl implements UserService {// 自动匹配UserDao类型的Bean(唯一实例)@Autowired private UserDao userDao; 
}

(2)构造器注入(推荐有参依赖场景)

@Service
public class UserServiceImpl implements UserService {private final UserDao userDao;// 单构造器可省略@Autowired(Spring4.3+特性)@Autowired public UserServiceImpl(UserDao userDao) { this.userDao = userDao;}
}

(3)Setter 方法注入(可选依赖场景)

@Service
public class UserServiceImpl implements UserService {private UserDao userDao;// 可选依赖:允许userDao为null(需配合@Nullable)@Autowired(required = false) public void setUserDao(UserDao userDao) { this.userDao = userDao;}
}

2. 精准匹配:@Qualifier 解决歧义​

当同一类型存在多个 Bean 时,通过@Qualifier(“beanId”)指定具体实例:

@Service
public class OrderService {// 存在多个DataSource时指定主库@Autowired @Qualifier("masterDataSource") private DataSource dataSource; 
}

3. 简单值注入:@Value​

注入基本类型、字符串或 EL 表达式结果:

@Service
public class UserServiceImpl {// 注入配置文件中的值@Value("${jdbc.username}") private String dbUser; // 注入固定值@Value("默认超时时间:3000ms") private String defaultTimeout; 
}

配置支持: 需在 XML 中添加<context:property-placeholder location=“classpath:config.properties”/>

三、Bean 高级特性:生命周期与作用域

1. 生命周期管理注解​

(1)初始化回调:@PostConstruct(替代 XML init-method)

@Service
public class CacheService {private Map<String, Object> cache;// Bean创建并注入依赖后执行@PostConstruct public void init() { cache = new ConcurrentHashMap<>();}
}

(2)销毁回调:@PreDestroy(替代 XML destroy-method)

@Service
public class DataSourceService {// Bean销毁前释放资源@PreDestroy public void close() { // 关闭数据库连接等操作}
}

2. 作用域控制:@Scope​

替代 XML 的scope属性,支持 4 种作用域(新增 WebFlux 相关作用域):

// 原型模式:每次注入创建新实例
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) 
@Service("userSession")
public class UserSession { ... }// Web环境专用(需添加spring-web依赖)
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) 
@Service("sessionCache")
public class SessionCache { ... }

**proxyMode:**解决作用域 Bean 注入到单例 Bean 时的生命周期问题(推荐使用 TARGET_CLASS 代理)

3. 延迟初始化:@Lazy​

推迟单例 Bean 的创建(首次使用时初始化):

@Service
@Lazy // 等价于XML的lazy-init="true"
public class HeavyService {// 资源密集型Bean延迟加载
}

四、企业级实战:注解与 XML 混合开发

1. 传统 SSM 框架整合(注解为主 + XML 为辅)​

(1)SpringMVC 配置(XML 保留核心组件)

<!-- web.xml -->
<servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param>
</servlet><!-- springmvc.xml:保留视图解析器等XML配置 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/"/><property name="suffix" value=".jsp"/>
</bean><!-- 开启注解驱动:替代XML的<mvc:annotation-driven/> -->
<mvc:annotation-driven/> 

(2)MyBatis 整合(全注解模式)

// 替代XML的MapperScannerConfigurer
@MapperScan("com.dao") // 扫描Mapper接口
@Configuration
public class MyBatisConfig {@Beanpublic SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {SqlSessionFactoryBean factory = new SqlSessionFactoryBean();factory.setDataSource(dataSource);factory.setTypeAliasesPackage("com.entity"); // 配置实体类别名return factory;}
}

2. 复杂场景:多条件 Bean 注册​

通过@Profile实现环境隔离(开发 / 测试 / 生产环境不同配置):

// 开发环境配置
@Profile("dev") 
@Configuration
public class DevConfig {@Beanpublic DataSource dataSource() {// 配置本地开发数据库}
}// 生产环境配置
@Profile("prod") 
@Configuration
public class ProdConfig {@Beanpublic DataSource dataSource() {// 配置线上数据库集群}
}

**激活方式:**通过 JVM 参数-Dspring.profiles.active=dev或 XML<beans profile="dev">

五、注解开发的优缺点与适用场景​

1. 核心优势​

  • 代码内聚性:Bean 定义与实现逻辑集中在类文件,避免 XML 与代码分离带来的上下文切换​
  • 类型安全:编译期检查依赖匹配错误(如 @Autowired 无匹配 Bean 时编译报错)​
  • 开发效率:消除大量 XML 模板代码,尤其适合快速迭代的互联网项目​

2. 潜在问题​

  • 隐式配置:依赖关系通过注解隐含在代码中,复杂场景下可读性低于 XML​
  • 框架侵入性:业务代码依赖 Spring 注解(如 @Service),增加框架迁移成本​
  • 调试难度:动态代理生成的 Bean 实例,堆栈跟踪时需区分原始类与代理类​

3. 最佳实践​

  • 分层使用:业务层(@Service)、持久层(@Repository)使用注解,基础设施层(数据源、事务管理器)保留 XML 或 @Bean 配置​
  • 组合使用:复杂条件配置用 @Conditional+@Profile,简单 Bean 用 @Component 系列注解​
  • 规范命名:Bean 的 id 统一使用@Component(“xxxService”)显式声明,避免依赖默认命名规则

六、从 XML 到注解:Spring 开发的演进逻辑

特性XML 配置模式注解模式
Bean 声明方式集中式 XML 文件分散在类文件中(@Component/@Bean
依赖注入方式显式隐式
@Autowired+@Qualifier
第三方组件整合必须 XML 配置@Bean + 编程式配置
团队协作友好度配置可见性高(适合新手)依赖关系隐含(需 IDE 辅助)

黑马教程核心启示: 注解开发的本质是 “约定大于配置”,通过注解简化重复劳动,但需掌握底层原理(如 Spring 如何解析 @Autowired、BeanPostProcessor 如何处理 @PostConstruct)。在企业级开发中,建议采用 “注解为主、XML 为辅” 的混合模式,兼顾效率与可维护性。​

总结:注解时代的 Spring 核心能力​
注解开发模式通过@ComponentScan、@Autowired等核心注解,将 Spring 的 IoC/DI 能力融入代码逻辑,实现 “零 XML” 配置的轻量化开发。掌握这套体系的关键在于:​

  • 精准选择注解:用 @Service/@Repository 明确分层,用 @Bean 处理第三方组件​
  • 理解自动装配规则:区分 byType(@Autowired)与 byName(@Qualifier)的适用场景​
  • 管理 Bean 生命周期:通过 @PostConstruct/@PreDestroy 替代 XML 的 init/destroy 方法​
  • 结合条件与作用域:利用 @Profile/@Scope 实现环境隔离与实例控制
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.dtcms.com/a/260179.html

相关文章:

  • 机器学习15-规则学习-知识加强
  • 【NLP】自然语言项目设计
  • vllm加载多个Lora部署
  • 数据分享:教育数据集-预测学生辍学风险和学术成功数据集
  • 01【C++ 入门基础】命名空间/域
  • 8、做中学 | 四年级下期 Golang运算符
  • [论文阅读] 人工智能 + 软件工程 | AI 与敏捷开发的破局之路:从挫败到成功的工作坊纪实
  • Git 使用规范与命令使用场景详解
  • 【嵌入式ARM汇编基础】-ELF文件格式内部结构详解(二)
  • C语言再出发:2025年AI时代的关键语言
  • JavaWeb学习——day9(图书管理系统初级)
  • Day 2 学习主题「面向对象 + Pythonic 风格」
  • Linux服务器部署Leantime与cpolar构建低成本团队协作环境
  • 数据分享:汽车行业-汽车属性数据集
  • 英特尔汽车业务败走中国,喊出“All in”才过两个月
  • 测试方法的分类
  • 香港维尔利健康科技集团推出AI辅助医学影像训练平台,助力医护人才数字化转型
  • aws(学习笔记第四十七课) codepipeline-docker-build
  • 深入解析设备管理系统新趋势:物联网与云原生驱动的智能化实践
  • 软件测试之基于博客系统项目的性能测试
  • 大数据赋能智慧城市:从数据洪流到科学规划的“智慧之匙”
  • 互联网医院系统源码解析:如何实现视频问诊、电子处方等核心功能?
  • 详解零拷贝
  • 面试150 验证回文串
  • 七天学会SpringCloud分布式微服务——02——第一个微服务项目
  • Redis-基本命令
  • Tailwind CSS 尺寸控制
  • 兰洋科技上合组织论坛发表专题分享,全球液冷布局引领绿色算力未来
  • 开发基于Jeston Orin Nx 开发版 16G的实现
  • YOLO+ONNX+PyQt打包为exe踩坑记录