📚 前言
这是我之前写 项目时的一些理解和感悟, 我喊了AI帮我润色了一下语言文字,发出来了,希望对大家有用
在学习Spring框架时,经常会遇到@Configuration、@Bean、@Service、@Resource等注解,以及各种设计模式的应用。本文通过具体的代码示例(MailConfig和MailService),深入浅出地解释这些概念,帮助理解Spring的核心机制。
🎯 核心问题
问题1:为什么需要@Configuration和@Bean?
问题2:为什么没有注解的类也能被@Resource注入?
问题3:构造函数参数与配置类的关系?
问题4:涉及了哪些设计模式?
让我们逐一解答这些问题。
🏭 第一部分:Spring容器 = 大仓库
🤔 没有Spring的痛苦
假设你要在3个地方发邮件:用户注册、密码重置、系统通知。
没有Spring配置的代码:
1// 第1个地方:用户注册 2public void register() { 3 // 每次都要写这一堆配置! 4 JavaMailSenderImpl sender = new JavaMailSenderImpl(); 5 sender.setHost("smtp.qq.com"); 6 sender.setPort(587); 7 sender.setUsername("myemail@qq.com"); 8 sender.setPassword("mypassword"); 9 10 Properties props = new Properties(); 11 props.put("mail.smtp.auth", "true"); 12 props.put("mail.smtp.ssl.enable", "true"); 13 props.put("mail.smtp.timeout", "5000"); 14 props.put("mail.smtp.connectiontimeout", "5000"); 15 props.put("mail.smtp.writetimeout", "5000"); 16 sender.setJavaMailProperties(props); 17 18 MailProperties mailProps = new MailProperties(); 19 mailProps.setUsername("myemail@qq.com"); 20 // ... 更多配置 21 22 MailService mailService = new MailService(sender, mailProps); 23 mailService.sendRegisterCode("user@email.com", "123456"); 24} 25 26// 第2个地方:密码重置 27public void resetPassword() { 28 // 又要写一遍同样的15行配置!!! 29 JavaMailSenderImpl sender = new JavaMailSenderImpl(); 30 sender.setHost("smtp.qq.com"); // 重复! 31 sender.setPort(587); // 重复! 32 sender.setUsername("myemail@qq.com"); // 重复! 33 // 又是15行重复配置... 34 35 MailService mailService = new MailService(sender, mailProps); 36 mailService.sendResetEmail("user@email.com"); 37} 38 39// 第3个地方:系统通知 40public void sendNotification() { 41 // 再写一遍同样的15行配置!!! 42 // 同样的重复代码... 43} 44
问题有多严重?
- 重复代码:同样的15行配置要写3次、5次、10次…
- 修改困难:如果邮箱密码变了,要改10个地方!
- 容易出错:某个地方配置写错了,邮件就发不出去
- 浪费时间:每次写业务代码都要先写配置
✨ Spring的解决方案:仓库管理
Spring容器就像一个大仓库,统一管理所有对象。
1@Configuration // "我是配置管理员" 2public class MailConfig { 3 4 @Bean // "我来准备现成的MailService放到仓库" 5 public MailService mailService(JavaMailSender sender, MailProperties props) { 6 // 复杂配置我来写,你不用管 7 return new MailService(sender, props); // 现成的产品放入仓库 8 } 9 10 @Bean // "我来准备现成的JavaMailSender放到仓库" 11 public JavaMailSender javaMailSender() { 12 JavaMailSenderImpl sender = new JavaMailSenderImpl(); 13 sender.setHost(env.getProperty("spring.mail.host")); 14 sender.setPort(Integer.parseInt(env.getProperty("spring.mail.port", "25"))); 15 sender.setUsername(env.getProperty("spring.mail.username")); 16 sender.setPassword(env.getProperty("spring.mail.password")); 17 18 Properties props = new Properties(); 19 props.put("mail.smtp.auth", "true"); 20 props.put("mail.smtp.ssl.enable", "true"); 21 props.put("mail.smtp.timeout", "5000"); 22 sender.setJavaMailProperties(props); 23 24 return sender; // 现成的邮件发送器放入仓库 25 } 26} 27
你的业务代码变得超简单:
1// 第1个地方:用户注册 2@Resource 3private MailService mailService; // 从仓库提货 4 5public void register() { 6 mailService.sendRegisterCode("user@email.com", "123456"); // 一行搞定! 7} 8 9// 第2个地方:密码重置 10@Resource 11private MailService mailService; // 还是从仓库提货 12 13public void resetPassword() { 14 mailService.sendResetEmail("user@email.com"); // 一行搞定! 15} 16 17// 第3个地方:系统通知 18@Resource 19private MailService mailService; // 依然从仓库提货 20 21public void sendNotification() { 22 mailService.sendNotification("通知内容"); // 一行搞定! 23} 24
🏪 第二部分:Bean进入仓库的两种方式
📦 方式1:贴标签自动入库
1@Service // ← 这就像给盒子贴了"请放入仓库"的标签 2public class UserService { 3 public void doSomething() { 4 // 业务逻辑 5 } 6} 7 8@Controller // ← 另一种标签 9public class UserController { 10} 11 12@Repository // ← 又一种标签 13public class UserRepository { 14} 15
工作流程:
1Spring启动 → 扫描所有类 → 发现@Service标签 → 自动创建UserService → 放入仓库 2
🚚 方式2:手动搬运入库
1// MailService没贴标签,Spring不会自动放入 2public class MailService { 3 private final JavaMailSender javaMailSender; 4 private final MailProperties mailProperties; 5 6 public MailService(JavaMailSender javaMailSender, MailProperties mailProperties) { 7 this.javaMailSender = javaMailSender; 8 this.mailProperties = mailProperties; 9 } 10} 11 12@Configuration 13public class MailConfig { 14 @Bean // ← 这里是"搬运工",手动把MailService放入仓库 15 public MailService mailService(JavaMailSender sender, MailProperties props) { 16 MailService service = new MailService(sender, props); // 手动创建 17 return service; // 手动放入仓库 18 } 19} 20
工作流程:
1Spring启动 → 发现MailConfig → 看到@Bean方法 → 调用这个方法 → 得到MailService → 放入仓库 2
🛍️ 从仓库取货
1@Resource // "仓库管理员,给我一个MailService" 2private MailService mailService; // Spring从仓库里拿给你 3 4// Spring不关心这个东西是怎么进仓库的(贴标签还是手动搬运) 5// 只要仓库里有,就能给你 6
关键理解:@Resource不看类有没有注解,只看仓库里有没有这个Bean!
🔗 第三部分:构造函数 = 需求清单
📋 MailService的需求清单
1public class MailService { 2 private final JavaMailSender javaMailSender; // 需求1:我要一个邮件发送器 3 private final MailProperties mailProperties; // 需求2:我要一个配置信息 4 5 // 构造函数 = "需求清单" 6 public MailService(JavaMailSender javaMailSender, MailProperties mailProperties) { 7 this.javaMailSender = javaMailSender; // 收下需求1 8 this.mailProperties = mailProperties; // 收下需求2 9 } 10 11 public void sendRegisterCode(String to, String code) throws Exception { 12 // 使用构造函数收到的 javaMailSender 发邮件 13 MimeMessage message = javaMailSender.createMimeMessage(); 14 15 // 使用构造函数收到的 mailProperties 获取配置 16 MimeMessageHelper helper = new MimeMessageHelper(message, false); 17 helper.setFrom(mailProperties.getUsername()); 18 helper.setTo(to); 19 helper.setSubject("注册验证码通知"); 20 21 String content = buildRegisterTemplate(code); 22 helper.setText(content, true); 23 24 javaMailSender.send(message); // 发送邮件 25 } 26} 27
🏭 MailConfig = 材料供应商
1@Configuration 2public class MailConfig { 3 4 @Bean 5 public MailService mailService(JavaMailSender javaMailSender, MailProperties mailProperties) { 6 // ↑ 材料1: Spring自动提供 ↑ 材料2: Spring自动提供 7 8 // Spring调用这个方法时会自动传入这两个参数 9 return new MailService(javaMailSender, mailProperties); 10 // ↑ 把材料1给MailService ↑ 把材料2给MailService 11 } 12} 13
🔄 完整的供需匹配过程
Step 1: MailService提出需求
1public MailService(JavaMailSender javaMailSender, MailProperties mailProperties) { 2 // "要造我,必须给我这两样材料" 3} 4
Step 2: Spring准备材料
1// Spring自己准备或者其他地方准备好了: 2JavaMailSender sender = ...; // 材料1准备好(可能是自动配置或其他@Bean提供) 3MailProperties props = ...; // 材料2准备好(可能是配置文件或其他@Bean提供) 4
Step 3: MailConfig组装
1@Bean 2public MailService mailService(JavaMailSender sender, MailProperties props) { 3 // Spring: "我把准备好的材料传给你" 4 // MailConfig: "好的,我用这些材料造MailService" 5 return new MailService(sender, props); // 用材料造产品 6} 7
Step 4: MailService收到材料开始工作
1public void sendRegisterCode(String to, String code) { 2 // 使用构造函数收到的现成材料工作,不用自己创建 3 javaMailSender.send(message); 4} 5
🎯 如果没有构造函数参数会怎样?
错误做法:MailService自己找材料
1public class MailService { 2 public void sendRegisterCode(String to, String code) { 3 // 每次都要自己创建!很麻烦!很容易出错! 4 JavaMailSenderImpl sender = new JavaMailSenderImpl(); 5 sender.setHost("smtp.qq.com"); 6 sender.setPort(587); 7 sender.setUsername("myemail@qq.com"); 8 sender.setPassword("mypassword"); 9 // ... 15行重复配置代码 10 11 sender.send(message); 12 } 13} 14
正确做法:通过构造函数接收现成的
1public class MailService { 2 private final JavaMailSender javaMailSender; // 别人给我准备好的 3 4 public MailService(JavaMailSender javaMailSender) { 5 this.javaMailSender = javaMailSender; // 接收别人准备的 6 } 7 8 public void sendRegisterCode(String to, String code) { 9 javaMailSender.send(message); // 直接用,不用自己配置 10 } 11} 12
🎨 第四部分:涉及的设计模式
1. 🏭 工厂模式(Factory Pattern)
问题: 创建复杂对象很麻烦,到处都要重复写创建代码。
解决: 专门的工厂类负责创建对象。
1// MailConfig = 邮件服务工厂 2@Configuration 3public class MailConfig { 4 5 @Bean // 工厂方法:专门创建MailService 6 public MailService mailService(JavaMailSender sender, MailProperties props) { 7 // 复杂的创建逻辑集中在这里 8 return new MailService(sender, props); 9 } 10 11 @Bean // 工厂方法:专门创建JavaMailSender 12 public JavaMailSender javaMailSender() { 13 JavaMailSenderImpl sender = new JavaMailSenderImpl(); 14 // 复杂的配置逻辑 15 sender.setHost(env.getProperty("spring.mail.host")); 16 sender.setPort(Integer.parseInt(env.getProperty("spring.mail.port"))); 17 // ... 更多复杂配置 18 return sender; 19 } 20} 21
工厂模式的好处:
- 创建逻辑集中管理
- 业务代码不需要关心如何创建对象
- 修改创建逻辑只需要改一个地方
2. 💉 依赖注入模式(Dependency Injection)
问题: 对象之间耦合度太高,A对象需要B对象时直接new B()。
解决: 外部注入依赖,而不是内部创建。
1// 错误做法:高耦合 2public class MailService { 3 public void sendMail() { 4 // 自己创建依赖,高耦合! 5 JavaMailSenderImpl sender = new JavaMailSenderImpl(); 6 sender.setHost("smtp.gmail.com"); // 写死了配置 7 sender.send(); 8 } 9} 10 11// 正确做法:依赖注入 12public class MailService { 13 private final JavaMailSender javaMailSender; // 依赖 14 15 // 构造器注入:外部传入依赖 16 public MailService(JavaMailSender javaMailSender) { 17 this.javaMailSender = javaMailSender; 18 } 19 20 public void sendMail() { 21 javaMailSender.send(); // 使用注入的依赖,低耦合! 22 } 23} 24
依赖注入的好处:
- 松耦合:MailService不关心JavaMailSender怎么创建
- 可测试:容易替换为Mock对象进行测试
- 灵活性:可以注入不同的实现
3. 🎯 策略模式(Strategy Pattern)
问题: 不同环境需要不同的配置策略。
解决: 根据条件选择不同的创建策略。
1@Configuration 2public class MailConfig { 3 4 // 策略1:优先使用Spring Boot自动配置的JavaMailSender 5 @Bean 6 @ConditionalOnMissingBean(MailService.class) // 条件:如果还没有MailService 7 public MailService mailService(JavaMailSender javaMailSender, MailProperties mailProperties) { 8 return new MailService(javaMailSender, mailProperties); 9 } 10 11 // 策略2:如果没有JavaMailSender,自己创建一个 12 @Bean 13 @ConditionalOnMissingBean(JavaMailSender.class) // 条件:如果还没有JavaMailSender 14 public JavaMailSender javaMailSender() { 15 // 从Environment读取Nacos配置,创建自定义的邮件发送器 16 JavaMailSenderImpl sender = new JavaMailSenderImpl(); 17 sender.setHost(env.getProperty("spring.mail.host")); 18 // ... 从配置中心读取配置 19 return sender; 20 } 21} 22
策略模式的体现:
- 本地application.yml有配置 → 使用策略1(Spring Boot自动配置)
- 只有Nacos远程配置 → 使用策略2(手动创建)
- 自动适配不同的部署环境
4. 🔌 适配器模式(Adapter Pattern)
问题: 配置来源(Environment)和目标对象(JavaMailSender)接口不匹配。
解决: 创建适配器转换接口。
1@Bean 2public JavaMailSender javaMailSender() { 3 JavaMailSenderImpl sender = new JavaMailSenderImpl(); 4 5 // 适配器:将Environment配置适配到JavaMailSender接口 6 sender.setHost(env.getProperty("spring.mail.host")); // 适配host 7 sender.setPort(Integer.parseInt(env.getProperty("spring.mail.port", "25"))); // 适配port 8 sender.setUsername(env.getProperty("spring.mail.username")); // 适配username 9 sender.setPassword(env.getProperty("spring.mail.password")); // 适配password 10 11 // 适配Properties配置 12 Properties props = new Properties(); 13 String timeout = env.getProperty("spring.mail.properties.mail.smtp.timeout", "5000"); 14 props.put("mail.smtp.timeout", timeout); 15 sender.setJavaMailProperties(props); 16 17 return sender; 18} 19
适配器模式的体现:
- Environment = 被适配者(配置源)
- javaMailSender()方法 = 适配器(转换逻辑)
- JavaMailSender = 目标接口(期望的接口)
🔄 第五部分:完整工作流程
📋 项目启动时的Bean创建流程
11. Spring Boot启动 2 ↓ 32. 扫描AutoConfiguration.imports文件 4 ↓ 53. 发现MailConfig配置类 6 ↓ 74. 处理@Bean方法: 8 - 检查:容器中有JavaMailSender吗? 9 * 有 → 直接使用 10 * 没有 → 调用javaMailSender()方法创建 11 ↓ 125. 处理@Bean方法: 13 - 检查:容器中有MailService吗? 14 * 有 → 跳过 15 * 没有 → 调用mailService()方法创建 16 ↓ 176. 将创建的Bean存储到Spring容器中 18 ↓ 197. 启动完成,Bean准备就绪 20
🛍️ 业务代码使用Bean的流程
1@Service 2public class UserService { 3 4 @Resource // 1. Spring看到@Resource注解 5 private MailService mailService; // 2. 从容器中查找MailService 6 // 3. 找到后注入到这个字段 7 8 public void registerUser(String email) { 9 // 4. 直接使用注入的MailService,一行搞定 10 mailService.sendRegisterCode(email, "123456"); 11 } 12} 13
🎯 关键理解
- @Configuration + @Bean = 工厂 + 生产线
- 构造函数参数 = 需求清单
- Spring容器 = 仓库管理员
- @Resource = 取货单
核心好处:
- 写一次配置,到处都能用
- 业务代码简洁,专注业务逻辑
- 修改配置只需要改一个地方
- 自动处理依赖关系
🎓 第六部分:学习要点总结
✅ Bean注册的两种方式
| 方式 | 使用场景 | 示例 |
|---|---|---|
| 类注解 | 简单业务类,不需要复杂配置 | @Service UserService |
| @Bean方法 | 需要复杂配置的对象 | MailService、DataSource |
✅ 注解职责分工
| 注解 | 作用位置 | 职责 |
|---|---|---|
| @Configuration | 类 | 标识配置类 |
| @Bean | 方法 | 标识Bean工厂方法 |
| @Service/@Controller | 类 | 标识业务组件 |
| @Resource/@Autowired | 字段/方法 | 依赖注入 |
✅ 设计模式实际应用
- 工厂模式 → 统一创建复杂对象
- 依赖注入 → 降低耦合度
- 策略模式 → 环境自适应
- 适配器模式 → 接口兼容
✅ 核心记忆口诀
- MailConfig = 服务员(提前准备好菜)
- 构造函数 = 订餐单(我要什么)
- Spring容器 = 仓库(统一管理)
- @Resource = 取货(直接用现成的)
💡 第七部分:常见问题解答
❓ Q1: 为什么MailService没有@Service注解也能用?
A1: 因为通过MailConfig的@Bean方法手动注册到了Spring容器。@Resource只看容器里有没有,不看类有没有注解。
❓ Q2: 构造函数参数是干什么用的?
A2: 构造函数参数是"需求清单",告诉Spring"要创建我需要这些材料"。MailConfig负责准备材料并传递给构造函数。
❓ Q3: 什么时候用@Service,什么时候用@Bean?
A3:
- 简单业务类用@Service(让Spring自动管理)
- 需要复杂配置的类用@Bean(手动控制创建过程)
❓ Q4: @Configuration和@Bean必须配合使用吗?
A4: 是的。@Configuration标识配置类,@Bean标识具体的Bean工厂方法,缺一不可。
🚀 第八部分:扩展应用
📦 类似的配置示例
1// 阿里云短信配置 2@Configuration 3public class AliSmsConfig { 4 5 @Bean("aliClient") 6 public Client client() { 7 Config config = new Config() 8 .setAccessKeyId(accessKeyId) 9 .setAccessKeySecret(accessKeySecret) 10 .setEndpoint(endpoint); 11 return new Client(config); // 复杂对象创建 12 } 13} 14 15// 数据库配置 16@Configuration 17public class DatabaseConfig { 18 19 @Bean 20 public DataSource dataSource() { 21 HikariDataSource dataSource = new HikariDataSource(); 22 dataSource.setJdbcUrl("jdbc:mysql://localhost/db"); 23 dataSource.setUsername("user"); 24 dataSource.setPassword("pass"); 25 dataSource.setMaximumPoolSize(20); // 复杂配置 26 return dataSource; 27 } 28} 29
🎯 最佳实践
- 配置类命名:以Config结尾,如MailConfig、DatabaseConfig
- Bean命名:使用@Bean(name=“xxx”)指定明确的名称
- 条件注解:使用@ConditionalOnMissingBean避免重复创建
- 配置分离:不同功能的配置放在不同的配置类中
📝 总结
通过MailConfig和MailService的例子,我们学习了:
- Spring容器的仓库管理机制
- Bean创建的两种方式(类注解 vs @Bean方法)
- 依赖注入的工作原理(构造函数参数的作用)
- 实际应用中的设计模式(工厂、依赖注入、策略、适配器)
核心思想: Spring帮我们做繁琐的对象创建和管理工作,我们专注于业务逻辑。这就是现代框架的价值 —— 让复杂的事情变简单,让重复的事情变自动。
记住:设计模式不是为了炫技,而是为了解决实际问题。在Spring中,这些模式的应用让我们的代码更加优雅、可维护、可扩展。
📧 第九部分:配置文件的作用机制
🎯 邮箱配置在Spring中的作用
根据你提供的配置文件,让我们分析邮箱配置是如何发挥作用的:
1spring: 2 mail: 3 host: smtp.qq.com 4 username: 454284665@qq.com # 登录账户 5 password: vdxewnwgchllbjha 6 port: 465 7 default-encoding: UTF-8 8 protocol: smtps 9
🔄 配置文件 → Spring容器 → Bean创建的完整流程
Step 1: Spring Boot启动时读取配置
1// Spring Boot会自动读取配置文件,创建MailProperties Bean 2@ConfigurationProperties(prefix = "spring.mail") 3public class MailProperties { 4 private String host; // 自动映射 spring.mail.host 5 private String username; // 自动映射 spring.mail.username 6 private String password; // 自动映射 spring.mail.password 7 private int port; // 自动映射 spring.mail.port 8 // ... 其他属性 9} 10
Step 2: Spring Boot自动配置邮件服务
1// Spring Boot内置的邮件自动配置类(你看不到,但它在工作) 2@Configuration 3@ConditionalOnProperty(name = "spring.mail.host") // 只有配置了host才生效 4public class MailSenderAutoConfiguration { 5 6 @Bean 7 @ConditionalOnMissingBean(JavaMailSender.class) 8 public JavaMailSender javaMailSender(MailProperties properties) { 9 JavaMailSenderImpl sender = new JavaMailSenderImpl(); 10 11 // 使用你配置文件中的值 12 sender.setHost(properties.getHost()); // smtp.qq.com 13 sender.setPort(properties.getPort()); // 465 14 sender.setUsername(properties.getUsername()); // 454284665@qq.com 15 sender.setPassword(properties.getPassword()); // vdxewnwgchllbjha 16 sender.setProtocol(properties.getProtocol()); // smtps 17 18 return sender; // 创建好的邮件发送器放入Spring容器 19 } 20} 21
Step 3: 你的MailConfig可以直接使用
1@Configuration 2public class MailConfig { 3 4 @Bean 5 public MailService mailService(JavaMailSender javaMailSender, MailProperties mailProperties) { 6 // 这两个参数Spring会自动注入: 7 // 1. javaMailSender - 来自Step 2的自动配置 8 // 2. mailProperties - 来自Step 1的配置文件映射 9 return new MailService(javaMailSender, mailProperties); 10 } 11} 12
📋 配置文件的三种作用方式
方式1: 自动配置(最常用)
1spring: 2 mail: 3 host: smtp.qq.com # Spring Boot自动创建JavaMailSender 4 username: xxx@qq.com # 自动配置所有邮件相关Bean 5 password: xxx 6
结果: Spring容器自动有了JavaMailSender和MailProperties
方式2: 手动覆盖自动配置
1@Configuration 2public class MailConfig { 3 4 // 如果你想自定义,可以手动创建,会覆盖自动配置 5 @Bean 6 @Primary // 优先使用这个 7 public JavaMailSender customJavaMailSender() { 8 JavaMailSenderImpl sender = new JavaMailSenderImpl(); 9 // 你的自定义配置... 10 return sender; 11 } 12} 13
方式3: 条件配置(我们之前讨论的)
1@Configuration 2public class MailConfig { 3 4 // 只有在没有JavaMailSender时才创建 5 @Bean 6 @ConditionalOnMissingBean(JavaMailSender.class) 7 public JavaMailSender javaMailSender(Environment env) { 8 // 从Nacos等配置中心读取配置 9 return createCustomSender(env); 10 } 11} 12
🎯 你的配置文件的具体作用
1spring: 2 mail: 3 host: smtp.qq.com # 邮件服务器地址 4 username: 454284665@qq.com # 发送邮件的账号 5 password: vdxewnwgchllbjha # QQ邮箱的授权码(不是QQ密码) 6 port: 465 # SMTPS安全端口 7 default-encoding: UTF-8 # 邮件编码 8 protocol: smtps # 使用SMTPS协议(SSL加密) 9
这些配置会自动变成:
1// Spring自动创建的MailProperties 2MailProperties mailProperties = new MailProperties(); 3mailProperties.setHost("smtp.qq.com"); 4mailProperties.setUsername("454284665@qq.com"); 5mailProperties.setPassword("vdxewnwgchllbjha"); 6mailProperties.setPort(465); 7mailProperties.setDefaultEncoding("UTF-8"); 8mailProperties.setProtocol("smtps"); 9 10// Spring自动创建的JavaMailSender 11JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); 12javaMailSender.setHost("smtp.qq.com"); 13javaMailSender.setUsername("454284665@qq.com"); 14javaMailSender.setPassword("vdxewnwgchllbjha"); 15javaMailSender.setPort(465); 16// ... 其他配置 17
🚀 完整的邮件发送流程
1// 1. 启动时:Spring读取配置文件 2spring.mail.host=smtp.qq.com 3spring.mail.username=454284665@qq.com 4 ↓ 5// 2. Spring自动创建Bean 6MailProperties + JavaMailSender → 放入容器 7 ↓ 8// 3. 你的MailService使用 9@Resource 10private MailService mailService; // 注入现成的 11 12public void sendEmail() { 13 mailService.sendRegisterCode("user@email.com", "123456"); 14 // 内部使用你配置的QQ邮箱发送邮件 15} 16
💡 为什么要这样设计?
传统方式(每次手动配置):
1public void sendEmail() { 2 // 每次发邮件都要写这些! 3 JavaMailSenderImpl sender = new JavaMailSenderImpl(); 4 sender.setHost("smtp.qq.com"); 5 sender.setUsername("454284665@qq.com"); 6 sender.setPassword("vdxewnwgchllbjha"); 7 sender.setPort(465); 8 // ... 10行配置代码 9 10 sender.send(message); // 终于能发邮件了 11} 12
Spring方式(配置一次,到处使用):
1# 配置文件:写一次 2spring: 3 mail: 4 host: smtp.qq.com 5 username: 454284665@qq.com 6 password: vdxewnwgchllbjha 7
1// 业务代码:到处用 2@Resource 3private MailService mailService; 4 5public void sendEmail() { 6 mailService.sendRegisterCode("user@email.com", "123456"); // 一行搞定! 7} 8
🔐 安全提醒
你的配置中的password vdxewnwgchllbjha 是QQ邮箱的授权码,不是你的QQ密码。这是QQ邮箱为第三方应用提供的专用密码,更安全。
获取QQ邮箱授权码的步骤:
- 登录QQ邮箱
- 设置 → 账户
- 开启SMTP服务
- 获取授权码
🎯 总结:配置文件的核心价值
- 配置与代码分离:邮箱配置放在配置文件,代码更干净
- 环境适配:开发环境用测试邮箱,生产环境用正式邮箱
- Spring自动装配:配置文件 → 自动创建Bean → 直接注入使用
- 统一管理:所有邮件相关配置集中在一个地方
配置文件就是Spring的"原料清单",告诉Spring要准备什么材料,Spring根据清单自动准备好所有Bean供你使用!
《Spring设计模式与依赖注入详解》 是转载文章,点击查看原文。