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 实现类本身

    <bean id="connection" class="com.xzit.factory.MyConnectionFactoryBean"/>

    // 获取复杂对象
    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

    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
    <set>
    <ref bean="dateConverter"/>
    </set>
    </property>
    </bean>

    <bean id="dateConverter" class="com.xzit.convert.DateConverter" p:pattern="yyyy/MM/dd"/>
  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("提交事务");
    }
}
相关推荐
小江的记录本1 小时前
【MySQL】《MySQL日志面试背诵版+思维导图》(核心考点 + MySQL 8.0最新优化)
java·数据库·后端·python·sql·mysql·面试
ComputerInBook1 小时前
C++ 17 相比 C++ 14 新增之特征
开发语言·c++·c++ 17
我命由我123451 小时前
Android Framework P2 - 开机启动 Zygote 进程、Zygote 的预加载机制
android·java·开发语言·python·java-ee·intellij-idea·zygote
JAVA面经实录9171 小时前
Java Codex 企业标准Prompt库
java·开发语言·prompt
摇曳的精灵1 小时前
直接关掉jar包,会影响没有执行完的任务吗
java·jar
yoyo_zzm1 小时前
PHP vs Java:后端语言终极选择指南
java·spring boot·后端·架构·php
Evand J1 小时前
【MATLAB例程】5个UAV 分布式围捕编队运动仿真 —— 基于PID控制
开发语言·分布式·matlab
m0_502724951 小时前
golang 、java、c++、javascript 语言switch case异同
java·javascript·c++·golang
Season4501 小时前
C++11并发支持库(condition_variable | future全家桶)
java·jvm·c++