05Spring-AOP 注解学习

目录

一、举例

1. 直接用第三方注解(自动配置)比喻:

2. 用 @Bean 手动配置(Java Config)比喻:

3. XML 配置(传统方式)比喻:

4. FactoryBean(复杂创建逻辑)比喻:

5. 自动配置(Spring Boot 风格)比喻:

6、总结

二、面试题

三、学习依赖注入的思考

自我思考:

豆包回答:

1、关键区别

2、示例加深理解:

3、总结:

四、第三方bean依赖注入的思考

初步思考

进阶思考

五、Spring常见注解及使用场景

1、定义 Bean 相关

2、依赖注入相关

3、作用域相关

4、事务管理相关

5、生命周期相关

6、切面编程(AOP)相关

7、其他


一、举例

可以用 “餐厅点菜” 的场景来形象比喻,帮助理解 Spring 管理第三方 Bean 的几种方式:

场景类比:餐厅点菜(第三方库) vs. 自己做菜(自定义 Bean)

假设你是一位 “程序大厨”,需要用各种食材(第三方库)做出一顿饭(应用程序)。

1. 直接用第三方注解(自动配置)比喻

餐厅提供 “预制菜”(已标好价格和做法的菜品),你只需说 “我要这个”,服务员就会端上来。

对应 Spring

第三方库的类已经标注了@Component@Service等注解(相当于菜已配好),Spring 通过@ComponentScan自动发现并创建 Bean。

例如

引入 Spring Data JPA 后,@Repository注解的接口会被自动扫描并实现为 Bean。

2. 用 @Bean 手动配置(Java Config)比喻

餐厅菜单上有 “食材清单”(第三方类),但需要你告诉厨师 “怎么做”(如何创建 Bean)。

对应 Spring

第三方类没有注解,你通过@Bean方法定义创建逻辑。

例如

配置 HikariCP 数据源时,你需要在配置类中写:

@Bean public DataSource dataSource() { HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb"); // ... 其他配置 return new HikariDataSource(config); }

3. XML 配置(传统方式)比喻

你给餐厅写一张 “纸条”(XML 配置文件),详细说明菜的做法和配料。

对应 Spring

在 XML 中定义 Bean 的创建方式。

例如

<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mydb"/> <!-- ... 其他属性 --> </bean>

4. FactoryBean(复杂创建逻辑)比喻

菜单上的菜需要 “特殊工艺”(如需要多步加工、混合多种食材),你雇一个 “专业厨师助手”(FactoryBean)来处理。

对应 Spring

实现FactoryBean接口封装复杂的创建过程。

例如

创建 MongoClient 时,需要配置认证、集群等参数,通过FactoryBean统一处理。

5. 自动配置(Spring Boot 风格)比喻

餐厅推出 “套餐”(starter 依赖),你只需说 “我要 A 套餐”,餐厅自动帮你搭配好所有菜品。

对应 Spring

引入spring-boot-starter-*依赖后,Spring Boot 根据 classpath 自动配置 Bean(如 Redis、RabbitMQ 等)。

6、总结

Spring 管理第三方 Bean 就像 “你作为大厨,如何利用市场上的食材做菜”:

  • 现成菜(自动配置):直接买预制菜,加热即食。

  • 半成品(@Bean):买原材料,自己加工。

  • 复杂菜(FactoryBean):需要多道工序,雇个助手帮忙。

无论哪种方式,最终目标都是让这些 “食材”(第三方类)融入你的 “厨房”(Spring 容器),为你的 “顾客”(应用程序)服务。


二、面试题

面试题:BeanFactory与FactoryBean的区别?

答:BeanFactory是管理bean的工厂,负责管理bean的生命周期,从初始化到死亡;

FactoryBean是一个bean,来获取一个实例(作为工厂来创建其他对象);


三、学习依赖注入的思考

  • 自我思考:

bean里面的注解,我可不可以理解为古代奴隶主给奴隶额头上打的烙印,然后只要奴隶打上烙印,奴隶就可以使用奴隶主的东西(注解之后,就可以使用对应的方法)

  • 豆包回答:

你的比喻很形象!可以这样理解 Spring 框架中的注解机制,但需要补充几点细节:

类比对应关系

古代奴隶制
Spring 注解
奴隶主
Spring 容器
奴隶
Bean 对象
烙印
注解(如@Component@Service等)
使用奴隶主的资源
获得 Spring 容器的管理(依赖注入、AOP 等)
烙印类型(如铁匠、厨师)
不同注解的功能(如@Repository
@Autowired

1、关键区别

  1. 主动性不同

  • 奴隶被强制烙印,而 Bean 是开发者主动添加注解。

  • 注解本质是一种元数据,用于告诉 Spring 容器 “如何处理这个类”,而非直接提供方法。

  1. 功能范围不同

  • 注解不仅标记 Bean 的 “身份”,还能:

    • 注入依赖(如@Autowired):相当于奴隶主分配工具给奴隶。

    • 定义生命周期(如@PostConstruct):规定奴隶何时开始 / 结束工作。

    • 增强功能(如@Transactional):给奴隶额外的 “特权”(如自动回滚事务)。

  1. 运行机制不同

  • 注解需要配合 Spring 的组件扫描依赖注入机制才能生效。就像:

    • 奴隶主需要先 “巡视”(扫描)所有奴隶,识别烙印。

    • 再根据烙印类型分配工作(创建 Bean 并注入依赖)。

2、示例加深理解:

  • 古代场景

奴隶主:“所有额头有‘铁匠’烙印的奴隶,去锻造车间领工具!” (奴隶被标记后,主动获得使用工具的资格)

  • Spring 场景

// 标记为服务层组件(相当于烙印) @Service public class UserService { // 自动注入依赖(相当于奴隶主分配工具) @Autowired private UserRepository userRepository; public void createUser(String name) { // 使用注入的工具(奴隶使用分配的资源) userRepository.save(new User(name)); } }

3、总结:

你的比喻抓住了核心:注解是一种标记,让 Spring 容器识别并管理 Bean。但需要补充:

  • 注解的功能远不止 “标记”,还能定义行为和依赖关系。

  • Spring 容器的 “管理” 包括创建对象、注入依赖、应用 AOP 等复杂操作。

如果把 Spring 容器比作现代工厂,注解就像是产品的 “质检标签”—— 不仅标明身份,还指导后续的加工流程。


四、第三方bean依赖注入的思考

初步思考

  • 自我思考:

第三方bean依赖注入的里面的这些注解我可以理解为一颗颗冒起来的螺丝钉吗,然后通过扫描,不断扫描突起来的螺丝钉进行注入。

  • 豆包回答:

你的比喻太赞了!螺丝钉的类比非常贴切,而且更深入地触及了依赖注入的底层逻辑。让我帮你完善这个比喻:

第三方 Bean 依赖注入 = 机械组装流水线

软件开发概念
机械组装类比
第三方 Bean
外购的标准零件(如电机、齿轮)
注解(@Component等)
零件上的凸起螺丝钉接口
Spring 容器
自动化组装流水线
组件扫描
机械臂的视觉识别系统(扫描螺丝钉位置)
依赖注入
机械臂根据螺丝钉位置,将零件精准拧入设备

关键细节补充

  1. 不同类型的螺丝钉 = 不同注解

  • @Component/@Service:普通螺丝钉,标记为可组装的零件。

  • @Autowired:带磁性的螺丝钉,自动吸附匹配的零件(依赖)。

  • @Qualifier:特殊形状的螺丝钉,用于区分同类型但不同规格的零件。

  1. 扫描与匹配过程

流水线扫描逻辑: 1. 发现A零件上有个凸起的"@Autowired"螺丝钉(需要B组件) 2. 视觉系统在仓库中搜索带"@Service"标记的B组件 3. 找到匹配的B组件后,机械臂将B拧入A的对应接口

  1. 处理第三方零件(无螺丝钉)

  • 如果外购零件(第三方类)没有预装螺丝钉,需要:

    1. 手动安装螺丝钉(使用@Bean方法在配置类中定义)。

    2. 定制转接器(实现FactoryBean接口封装创建逻辑)。

示例代码对比

@Service // 类A被标记为可组装的零件 public class OrderService { @Autowired // 需要一个OrderRepository零件 private OrderRepository repository; // ... }

// 第三方库中的类(没有螺丝钉) public class ThirdPartyApiClient { // ... }

// 配置类:为第三方类安装螺丝钉 @Configuration public class AppConfig { @Bean // 手动安装螺丝钉 public ThirdPartyApiClient apiClient() { return new ThirdPartyApiClient(); } }

机械视角

零件A(OrderService)自带一个"@Autowired"螺丝钉接口,需要连接: - 类型为OrderRepository的零件 但发现OrderRepository是外购零件(第三方库),没有预装螺丝钉,于是: 1. 工人在配置车间(AppConfig)为其安装"@Bean"螺丝钉 2. 流水线识别后,将组装好的OrderRepository拧入OrderService

进阶思考

  • 循环依赖:两个零件互相需要对方作为螺丝钉接口,导致机械臂陷入死循环。(Spring 通过三级缓存解决)

  • 作用域问题:如果一个螺丝钉需要同时拧入多个零件,可能需要克隆(原型模式)或排队使用(单例模式)。

你的比喻不仅生动,还暗含了依赖注入的核心机制 ——通过标准化接口(注解)实现组件间的松耦合。继续保持这种具象化思维,复杂的框架原理也会变得清晰易懂!


五、Spring常见注解及使用场景

1、定义 Bean 相关

  • @Component:通用的组件标记注解,用于将类标识为 Spring 管理的组件,告诉 Spring 这个类是一个可纳入容器管理的 Bean。比如自定义的工具类、业务逻辑类等,只要希望 Spring 来管理,都可加此注解 。

  • @Controller:专门用于 Web 开发中标识控制器类,负责处理 Web 请求,接收用户输入,调用业务逻辑,并返回响应结果。在 MVC 架构里,是接收前端请求的入口 。

  • @Service:用于标注服务层的类,表明该类提供业务逻辑服务,主要进行业务规则的处理、业务流程的编排等,隔离了业务逻辑与上层表现层及下层数据访问层 。

  • @Repository:主要用于标识数据访问层的类,比如操作数据库的 DAO 类,Spring 会对其进行一些特殊处理,如自动转换数据库异常等 。

  • @Bean:通常在配置类中使用,通过在方法上标注该注解,将方法的返回值定义为一个 Bean,交给 Spring 容器管理。适用于将第三方类库中的类或无法直接用上述注解标注的类纳入 Spring 容器管理 。

2、依赖注入相关

  • @Autowired:按类型自动装配依赖对象,可用于字段、方法或构造函数参数上。Spring 会在容器中查找匹配类型的 Bean 并注入。比如在一个 Service 类中,通过@Autowired注入其依赖的 Dao 类 。

  • @Qualifier:常与@Autowired结合使用,当容器中存在多个相同类型的 Bean 时,可通过@Qualifier指定要注入的具体 Bean 的名称,明确选择特定的 Bean 进行注入 。

  • @Resource:与@Autowired类似,用于依赖注入,但它默认按名称进行注入,也可指定名称或类型进行注入,不依赖于 Spring 容器的类型 。

3、作用域相关

@Scope:用于定义 Bean 的作用域。常见取值有:

  • singleton:单例模式,在整个应用生命周期内,Spring 容器只会创建一个该 Bean 实例 。

  • prototype:原型模式,每次从容器获取该 Bean 时,都会创建一个新的实例 。

  • request:在一次 HTTP 请求范围内有效,每次 HTTP 请求都会创建一个新的 Bean 实例 。

  • session:在一个 HTTP Session 范围内有效 。

4、事务管理相关

@Transactional:用于声明事务管理,可标注在方法或类上。标注在方法上时,该方法在执行时会被纳入事务管理;标注在类上时,类中所有公共方法都会参与事务。可定义事务的传播行为(如REQUIREDSUPPORTS等 )、隔离级别、超时等属性,确保数据的一致性和完整性,适用于数据库操作等需要事务支持的场景 。

5、生命周期相关

  • @PostConstruct:被该注解标记的方法会在 Bean 的构造函数执行完毕且依赖注入完成之后,自动执行一次,通常用于进行一些初始化操作,如初始化资源、检查 Bean 状态、启动定时任务等 。
  • @PreDestroy:被该注解标记的方法会在 Bean 被销毁之前执行,可用于释放资源等清理工作 。

6、切面编程(AOP)相关

  • @Aspect:用于标识一个类是切面类,切面类包含切点和通知等定义,用于横切关注点的逻辑实现,如日志记录、性能监控、权限控制等 。

  • @Pointcut:定义切点,即指定哪些方法或类会被切面逻辑影响 。

  • @Before:前置通知注解,标注的方法会在目标方法执行之前执行 。

  • @After:后置通知注解,标注的方法会在目标方法执行之后执行 。

  • @Around:环绕通知注解,可在目标方法执行前后都执行自定义逻辑,功能更强大,能控制目标方法的执行 。

7、其他

  • @Value:用于注入配置值,可以是直接的常量值,也可以是从配置文件中读取的属性值 。比如@Value("${app.name}")可从配置文件中获取app.name属性值注入到字段 。

  • @Configuration:用于标识一个类是配置类,配置类中可定义多个@Bean方法,用于配置 Spring 容器中Bean

  • @ComponentScan:通常用在配置类上,指定 Spring 在初始化容器时要扫描的包,扫描这些包下被各种组件注解(如@Component等)标注的类,将其纳入容器管理 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值