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("提交事务");
    }
}
相关推荐
长不胖的路人甲2 小时前
斐波那契查找Java 实现 + 完整思路
java·开发语言
星恒随风2 小时前
C++ 继承进阶:默认成员函数、多继承、虚继承与组合设计
开发语言·c++·笔记·学习
祐樹2 小时前
1987年5月25日下午15-17点出生性格、运势和命运
java
Yeauty2 小时前
用 Whisper 转录前,你不用再离开 Rust
开发语言·rust·ffmpeg·音视频·视频
dkbnull2 小时前
Spring Boot依赖注入方式对比详解
spring boot·spring
电子云与长程纠缠2 小时前
UE中使用TGuardValue与TInlineComponentArray数据结构
开发语言·数据结构·学习·ue5·游戏引擎
正儿八经的少年2 小时前
Spring 事务保证数据一致性
java·数据库·spring
Lakers-242 小时前
1987年5月29日晚上19-21点出生性格、运势和命运
java
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题 第194题】【08_Kafka篇】第10题:简述 Kafka 的 Rebalance 机制?
java·kafka·消费者组·rebalance·分布式消息队列
呜喵王阿尔萨斯2 小时前
C/C++ const -- 多义混乱
c语言·开发语言·c++