1 复杂对象的创建
在 Spring 中,除了管理自己编写的 JavaBean,对于数据库连接、SqlSessionFactory 这类复杂对象,无法直接通过 new 或简单反射创建,需要用工厂方式管理,Spring 提供 FactoryBean、实例工厂、静态工厂 三种方案。
1.1 FactoryBean 接口
FactoryBean 是 Spring 提供的工厂接口,专门用于创建复杂对象,实现该接口需重写 3 个方法:
- T getObject():创建并返回最终的复杂对象
- Class<?> getObjectType():返回复杂对象的 Class 类型
- boolean isSingleton():默认返回 true,标识对象是单例
使用规则
-
直接根据 id 获取:拿到的是
getObject()返回的对象 -
id 前加
<bean id="connection" class="com.xzit.factory.MyConnectionFactoryBean"/>&获取:拿到的是 FactoryBean 实现类本身// 获取复杂对象
Connection conn = (Connection) context.getBean("connection");
// 获取工厂本身
MyConnectionFactoryBean factory = (MyConnectionFactoryBean) context.getBean("&connection");
1.2 自定义 FactoryBean 原理
底层通过反射调用 FactoryBean 实现类的 getObject () 完成对象创建:
- 解析 XML 获取 FactoryBean 实现类全类名
- 反射创建工厂实例
- 调用
getObject()得到复杂对象 - 根据
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 自定义转换器步骤
-
实现
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;
}
} -
注册转换器(id 固定为
conversionService)<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<bean id="dateConverter" class="com.xzit.convert.DateConverter" p:pattern="yyyy/MM/dd"/>
<property name="converters">
<set>
<ref bean="dateConverter"/>
</set>
</property>
</bean> -
使用:配置后 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("提交事务");
}
}