Spring学习日记——DAY04(复杂对象创建,AOP静态代理)

1 复杂对象的创建

在 Spring 中,除了管理自己编写的 JavaBean,对于数据库连接、SqlSessionFactory 这类复杂对象,无法直接通过 new 或简单反射创建,需要用工厂方式管理,Spring 提供 FactoryBean、实例工厂、静态工厂 三种方案。

1.1 FactoryBean 接口

FactoryBean 是 Spring 提供的工厂接口,专门用于创建复杂对象,实现该接口需重写 3 个方法:

  • T getObject():创建并返回最终的复杂对象
  • Class<?> getObjectType():返回复杂对象的 Class 类型
  • boolean isSingleton():默认返回 true,标识对象是单例
使用规则
  • 直接根据 id 获取:拿到的是 getObject() 返回的对象

  • id 前加 & 获取:拿到的是 FactoryBean 实现类本身

    // 获取复杂对象
    Connection conn = (Connection) context.getBean("connection");
    // 获取工厂本身
    MyConnectionFactoryBean factory = (MyConnectionFactoryBean) context.getBean("&connection");

1.2 自定义 FactoryBean 原理

底层通过反射调用 FactoryBean 实现类的 getObject () 完成对象创建:

  1. 解析 XML 获取 FactoryBean 实现类全类名
  2. 反射创建工厂实例
  3. 调用 getObject() 得到复杂对象
  4. 根据 isSingleton() 决定是否缓存

1.3 普通工厂方式创建

1.3.1 实例工厂

先创建工厂实例,再调用工厂的非静态方法创建对象:

复制代码
<!-- 配置工厂实例 -->
<bean id="instanceFactory" class="com.xzit.factory.InstanceFactory"/>
<!-- 工厂创建对象 -->
<bean id="conn" factory-bean="instanceFactory" factory-method="getConnection"/>
1.3.2 静态工厂

直接调用工厂类的静态方法创建对象,无需创建工厂实例:

复制代码
<bean id="staticConn" class="com.xzit.factory.StaticFactory" factory-method="getConnection"/>

2 类型转换器

Spring 内置基础类型转换器,但日期、自定义类型等复杂转换需要手动配置。

2.1 自定义转换器步骤

  1. 实现 Converter<S, T> 接口,重写 convert 方法

    • S:源类型
    • T:目标类型

    public class DateConverter implements Converter<String, LocalDate> {
    private String pattern;
    @Override
    public LocalDate convert(String source) {
    DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern);
    return LocalDate.parse(source, df);
    }
    // setter 注入格式
    public void setPattern(String pattern) {
    this.pattern = pattern;
    }
    }

  2. 注册转换器(id 固定为 conversionService







  3. 使用:配置后 Spring 可自动将字符串转为指定日期类型


3 AOP 面向切面编程

3.1 AOP 简介

AOP(Aspect Oriented Programming):面向切面编程 ,核心是横向抽取重复代码,在不修改原业务代码的前提下,统一添加功能(权限、日志、事务、性能监控),实现解耦。

3.2 代理模式

AOP 底层基于动态代理实现,分为静态代理、JDK 动态代理、CGLIB 动态代理。

3.2.1 静态代理
  • 定义:代理类与目标类实现相同接口,代理类持有目标对象,在调用目标方法前后增强
  • 优点:简单直观
  • 缺点:耦合高、一个接口需一个代理类,不符合开闭原则
java 复制代码
// 共同接口
public interface Service { void save(); }
// 目标类
public class UserService implements Service {
    public void save() { System.out.println("保存用户"); }
}
// 代理类
public class ServiceProxy implements Service {
    private UserService target;
    public ServiceProxy(UserService target) { this.target = target; }
    public void save() {
        System.out.println("开启事务");
        target.save();
        System.out.println("提交事务");
    }
}
相关推荐
小锋java12348 分钟前
【技术专题】LangChain4j 开发Java Agent智能体 - 嵌入模型与向量数据库
java·人工智能
程序员皮皮林14 分钟前
Dubbo 的 SPI 和 JDK 的 SPI 有什么区别?
java·开发语言·dubbo
小锋java123414 分钟前
10分钟学会Java16新特性record
java
是多巴胺不是尼古丁17 分钟前
java‘期末复习--多态
java·开发语言
瑞雪兆丰年兮20 分钟前
[从0开始学Java|第二十五天]项目阶段(综合练习&斗地主小游戏)
java·windows
abcy07121330 分钟前
sqlalchemy 原生sql判断条件是否为空,为空则跳过
开发语言·python
.千余35 分钟前
【C++】深挖STL list底层:解迭代器与节点存储逻辑
开发语言·c++·笔记·学习·其他
Demon1_Coder36 分钟前
Day4-微服务-Seata默认事务
java·数据库·微服务
淡水瑜37 分钟前
C# 实操
开发语言·c#
雪落漂泊38 分钟前
C++ 继承与多态(上)
开发语言·c++