一、Spring IOC 深度解析
1.1 IOC 概述
什么是 IOC
IOC(Inversion of Control,控制反转) 是一种设计思想,它将对象的创建、依赖关系的管理从应用程序代码中剥离出来,交给外部容器(Spring IOC 容器)来管理。
传统方式 vs IOC
java
// 传统方式:对象自己控制依赖
public class UserService {
// 主动创建依赖对象
private UserDao userDao = new UserDaoImpl();
public User getUser(Long id) {
return userDao.findById(id);
}
}
// IOC 方式:依赖由容器注入
public class UserService {
// 声明依赖,由容器注入
@Autowired
private UserDao userDao;
public User getUser(Long id) {
return userDao.findById(id);
}
}
控制反转体现在:
- 对象创建权的反转:从应用程序手动创建 → 容器自动创建
- 依赖关系的反转:从主动获取依赖 → 被动接收依赖
DI(依赖注入)
DI(Dependency Injection,依赖注入) 是实现 IOC 的一种方式,通过容器将依赖的对象注入到目标对象中。
IOC 是设计思想
↓
DI 是实现方式
IOC 的核心作用
| 作用 | 说明 | 优势 |
|---|---|---|
| 降低耦合 | 对象间通过接口依赖,不直接依赖实现 | 易于替换实现 |
| 提高可测试性 | 依赖可以被 Mock 对象替换 | 便于单元测试 |
| 统一管理 | 对象生命周期由容器管理 | 便于资源管理 |
| 延迟加载 | 支持懒加载,按需创建对象 | 优化启动时间 |
| 单例管理 | 默认单例模式,节省资源 | 提高性能 |
1.2 IOC 容器核心接口
容器接口体系
BeanFactory (顶层接口)
↓
ListableBeanFactory
↓
HierarchicalBeanFactory
↓
ConfigurableBeanFactory
↓
ApplicationContext (核心接口)
↓
ConfigurableApplicationContext
↓
AbstractApplicationContext
↓
ClassPathXmlApplicationContext / AnnotationConfigApplicationContext
BeanFactory(Bean 工厂)
BeanFactory 是 Spring IOC 容器的顶层接口,定义了最基本的容器功能。
java
package org.springframework.beans.factory;
public interface BeanFactory {
// 获取 Bean 实例
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
// 判断容器是否包含指定 Bean
boolean containsBean(String name);
// 判断 Bean 是否为单例
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
// 判断 Bean 是否为原型
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
// 获取 Bean 的类型
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
// 获取 Bean 的别名
String[] getAliases(String name);
}
特点:
- 延迟加载:调用
getBean()时才创建 Bean - 轻量级:基础功能,内存占用小
ApplicationContext(应用上下文)
ApplicationContext 继承自 BeanFactory,提供了更丰富的企业级功能。
java
package org.springframework.context;
public interface ApplicationContext extends
EnvironmentCapable, // 环境配置
ListableBeanFactory, // 枚举所有 Bean
HierarchicalBeanFactory, // 父子容器
MessageSource, // 国际化
ApplicationEventPublisher, // 事件发布
ResourcePatternResolver // 资源加载
{
// 获取容器 ID
String getId();
// 获取容器显示名称
String getDisplayName();
// 获取容器启动时间
long getStartupDate();
// 获取父容器
ApplicationContext getParent();
// 获取 AutowireCapableBeanFactory(支持自动装配)
AutowireCapableBeanFactory getAutowireCapableBeanFactory()
throws IllegalStateException;
}
ApplicationContext 的额外功能:
java
// 1. 国际化支持
String getMessage(String code, Object[] args, Locale locale);
// 2. 事件发布机制
void publishEvent(ApplicationEvent event);
// 3. 资源加载
Resource[] getResources(String locationPattern);
// 4. 环境抽象
Environment getEnvironment();
BeanFactory vs ApplicationContext
| 特性 | BeanFactory | ApplicationContext |
|---|---|---|
| Bean 加载 | 延迟加载(Lazy) | 立即加载(Eager) |
| 国际化 | 不支持 | 支持 |
| 事件发布 | 不支持 | 支持 |
| 资源加载 | 不支持 | 支持 |
| AOP 支持 | 需要手动配置 | 自动支持 |
| BeanPostProcessor | 需要手动注册 | 自动注册 |
| 应用场景 | 资源受限环境 | 企业级应用 |
1.3 Bean 的生命周期
完整生命周期流程
1. 实例化 Bean
↓
2. 设置 Bean 属性(依赖注入)
↓
3. 检查 Aware 相关接口并设置
- BeanNameAware
- BeanClassLoaderAware
- BeanFactoryAware
↓
4. BeanPostProcessor 前置处理
- postProcessBeforeInitialization()
↓
5. 初始化 Bean
- @PostConstruct
- InitializingBean.afterPropertiesSet()
- init-method
↓
6. BeanPostProcessor 后置处理
- postProcessAfterInitialization()(AOP 代理在这里)
↓
7. Bean 使用中
↓
8. 销毁 Bean
- @PreDestroy
- DisposableBean.destroy()
- destroy-method
生命周期源码分析
AbstractAutowireCapableBeanFactory.doCreateBean()
java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd,
@Nullable Object[] args) {
// 1. 实例化 Bean
BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
Object bean = instanceWrapper.getWrappedInstance();
// 允许提前暴露单例 Bean(解决循环依赖)
boolean earlySingletonExposure = (mbd.isSingleton() &&
this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 2. 填充 Bean 属性(依赖注入)
populateBean(beanName, mbd, instanceWrapper);
// 3. 初始化 Bean
Object exposedObject = initializeBean(beanName, bean, mbd);
return exposedObject;
}
initializeBean() 详解
java
protected Object initializeBean(String beanName, Object bean,
@Nullable RootBeanDefinition mbd) {
// 3.1 调用 Aware 接口方法
invokeAwareMethods(beanName, bean);
Object wrappedBean = bean;
// 3.2 BeanPostProcessor 前置处理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 3.3 调用初始化方法
try {
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
// 3.4 BeanPostProcessor 后置处理(AOP 代理在这里创建)
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
invokeAwareMethods() - 调用 Aware 接口
java
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(
AbstractAutowireCapableBeanFactory.this);
}
}
}
invokeInitMethods() - 执行初始化方法
java
protected void invokeInitMethods(String beanName, Object bean,
@Nullable RootBeanDefinition mbd) {
// 1. 先执行 InitializingBean 接口
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null ||
!mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
((InitializingBean) bean).afterPropertiesSet();
}
// 2. 再执行自定义 init-method
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
生命周期回调示例
java
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class LifecycleBean implements
BeanNameAware, // 感知 Bean 名称
BeanFactoryAware, // 感知 BeanFactory
ApplicationContextAware, // 感知 ApplicationContext
InitializingBean, // 初始化回调
DisposableBean // 销毁回调
{
private String beanName;
private BeanFactory beanFactory;
private ApplicationContext applicationContext;
public LifecycleBean() {
System.out.println("1. 构造器:实例化 Bean");
}
// 属性注入
private String property;
public void setProperty(String property) {
System.out.println("2. 属性注入:setProperty = " + property);
this.property = property;
}
// Aware 接口
@Override
public void setBeanName(String name) {
System.out.println("3. BeanNameAware:setBeanName = " + name);
this.beanName = name;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
System.out.println("4. BeanFactoryAware:setBeanFactory");
this.beanFactory = beanFactory;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
System.out.println("5. ApplicationContextAware:setApplicationContext");
this.applicationContext = applicationContext;
}
// 初始化方法
@PostConstruct
public void postConstruct() {
System.out.println("6. @PostConstruct:初始化");
}
@Override
public void afterPropertiesSet() {
System.out.println("7. InitializingBean:afterPropertiesSet");
}
public void initMethod() {
System.out.println("8. init-method:自定义初始化方法");
}
// 销毁方法
@PreDestroy
public void preDestroy() {
System.out.println("9. @PreDestroy:准备销毁");
}
@Override
public void destroy() {
System.out.println("10. DisposableBean:destroy");
}
public void destroyMethod() {
System.out.println("11. destroy-method:自定义销毁方法");
}
}
配置文件
xml
<bean id="lifecycleBean" class="com.example.LifecycleBean"
init-method="initMethod"
destroy-method="destroyMethod">
<property name="property" value="test"/>
</bean>
或使用注解配置
java
@Configuration
public class AppConfig {
@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
public LifecycleBean lifecycleBean() {
LifecycleBean bean = new LifecycleBean();
bean.setProperty("test");
return bean;
}
}
输出结果:
1. 构造器:实例化 Bean
2. 属性注入:setProperty = test
3. BeanNameAware:setBeanName = lifecycleBean
4. BeanFactoryAware:setBeanFactory
5. ApplicationContextAware:setApplicationContext
6. @PostConstruct:初始化
7. InitializingBean:afterPropertiesSet
8. init-method:自定义初始化方法
... Bean 使用中 ...
9. @PreDestroy:准备销毁
10. DisposableBean:destroy
11. destroy-method:自定义销毁方法
1.4 依赖注入原理
依赖注入的三种方式
1. 构造器注入
java
@Service
public class UserService {
private final UserDao userDao;
private final EmailService emailService;
// 推荐:单个构造器可省略 @Autowired
public UserService(UserDao userDao, EmailService emailService) {
this.userDao = userDao;
this.emailService = emailService;
}
}
优点:
- 依赖不可变(final)
- 依赖不可为 null
- 完全初始化后才能使用
- 易于测试
源码实现:
java
// ConstructorResolver.autowireConstructor()
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors,
@Nullable Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
Object[] argsToUse = null;
// 1. 确定构造器
if (chosenCtors != null) {
constructorToUse = chosenCtors[0];
} else {
Constructor<?>[] candidates = mbd.getBeanClass().getDeclaredConstructors();
// 选择最匹配的构造器
constructorToUse = determineConstructor(candidates, ...);
}
// 2. 解析构造器参数
argsToUse = resolveConstructorArguments(beanName, mbd, constructorToUse);
// 3. 使用反射创建实例
Object beanInstance = instantiate(beanName, mbd, constructorToUse, argsToUse);
bw.setBeanInstance(beanInstance);
return bw;
}
2. Setter 注入
java
@Service
public class UserService {
private UserDao userDao;
private EmailService emailService;
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Autowired
public void setEmailService(EmailService emailService) {
this.emailService = emailService;
}
}
优点:
- 灵活性高
- 支持可选依赖(
@Autowired(required = false)) - 可以重新配置
源码实现:
java
// AutowiredAnnotationBeanPostProcessor.postProcessProperties()
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean,
String beanName) {
// 1. 查找需要注入的字段和方法
InjectionMetadata metadata = findAutowiringMetadata(beanName,
bean.getClass(), pvs);
// 2. 执行注入
try {
metadata.inject(bean, beanName, pvs);
} catch (BeanCreationException ex) {
throw ex;
}
return pvs;
}
// InjectionMetadata.inject()
public void inject(Object target, @Nullable String beanName,
@Nullable PropertyValues pvs) {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
// 调用每个元素的注入方法
element.inject(target, beanName, pvs);
}
}
}
3. 字段注入
java
@Service
public class UserService {
@Autowired
private UserDao userDao;
@Autowired
private EmailService emailService;
}
优点:
- 代码简洁
缺点:
- 无法注入 final 字段
- 不利于单元测试
- 隐藏依赖关系
源码实现:
java
// AutowiredFieldElement.inject()
@Override
protected void inject(Object bean, @Nullable String beanName,
@Nullable PropertyValues pvs) {
Field field = (Field) this.member;
Object value;
try {
// 1. 解析依赖
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
// 2. 从容器获取依赖对象
value = beanFactory.resolveDependency(desc, beanName,
autowiredBeanNames, typeConverter);
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(...);
}
if (value != null) {
// 3. 设置字段可访问
ReflectionUtils.makeAccessible(field);
// 4. 使用反射注入
field.set(bean, value);
}
}
依赖查找源码
DefaultListableBeanFactory.resolveDependency()
java
@Override
public Object resolveDependency(DependencyDescriptor descriptor,
@Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames,
@Nullable TypeConverter typeConverter) {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
// 1. 处理 Optional
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
// 2. 处理 ObjectFactory/Provider
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
// 3. 处理 @Lazy 注解
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
// 4. 常规依赖解析
Object result = getAutowireCandidateResolver()
.getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
if (result == null) {
// 5. 执行实际的依赖查找
result = doResolveDependency(descriptor, requestingBeanName,
autowiredBeanNames, typeConverter);
}
return result;
}
}
// 实际执行依赖查找
public Object doResolveDependency(DependencyDescriptor descriptor,
@Nullable String beanName,
@Nullable Set<String> autowiredBeanNames,
@Nullable TypeConverter typeConverter) {
// 1. 处理 @Value 注解
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class<?> type = descriptor.getDependencyType();
// 2. 处理集合类型依赖(Map、List、Array)
Object multipleBeans = resolveMultipleBeans(descriptor, beanName,
autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 3. 查找匹配的 Bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type,
descriptor);
if (matchingBeans.isEmpty()) {
// 没有找到匹配的 Bean
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
// 4. 多个候选 Bean,需要选择
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
// 无法确定唯一 Bean,抛出异常
throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
}
return null;
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
} else {
// 5. 只有一个候选 Bean
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
// 6. 记录依赖关系
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
// 7. 返回实例
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
return instanceCandidate;
}
确定唯一候选 Bean 的策略:
java
protected String determineAutowireCandidate(Map<String, Object> candidates,
DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
// 1. @Primary 注解
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
// 2. @Priority 注解(优先级)
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// 3. Bean 名称匹配
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}
循环依赖解决
三级缓存机制:
java
public class DefaultSingletonBeanRegistry {
// 一级缓存:完整的单例 Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 二级缓存:早期的 Bean 引用(已实例化,未初始化)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// 三级缓存:Bean 工厂(用于创建早期引用)
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 获取单例 Bean
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1. 从一级缓存获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 2. 从二级缓存获取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 3. 从三级缓存获取工厂
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 4. 通过工厂创建早期引用
singletonObject = singletonFactory.getObject();
// 5. 放入二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 6. 从三级缓存移除
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
}
循环依赖示例:
java
@Service
public class A {
@Autowired
private B b;
}
@Service
public class B {
@Autowired
private A a;
}
解决流程:
1. 创建 A:
- 实例化 A(调用构造器)
- 将 A 的工厂放入三级缓存
- 填充 A 的属性,需要 B
2. 创建 B:
- 实例化 B
- 将 B 的工厂放入三级缓存
- 填充 B 的属性,需要 A
3. 再次获取 A:
- 从三级缓存获取 A 的工厂
- 创建 A 的早期引用
- 将早期引用放入二级缓存
- 返回 A 的早期引用给 B
4. 完成 B 的创建:
- B 持有 A 的早期引用
- B 初始化完成
- B 放入一级缓存
5. 完成 A 的创建:
- A 持有完整的 B
- A 初始化完成
- A 放入一级缓存
注意:
- ✅ 构造器循环依赖无法解决(Bean 还未实例化)
- ✅ Setter/字段注入循环依赖可以解决
- ✅ 原型模式循环依赖无法解决
1.5 源码分析
IOC 容器启动流程
AnnotationConfigApplicationContext 启动源码:
java
public class AnnotationConfigApplicationContext extends GenericApplicationContext
implements AnnotationConfigRegistry {
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 1. 调用无参构造器
this();
// 2. 注册配置类
register(componentClasses);
// 3. 刷新容器(核心)
refresh();
}
public AnnotationConfigApplicationContext() {
// 创建 Bean 定义读取器
this.reader = new AnnotatedBeanDefinitionReader(this);
// 创建类路径扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
}
AbstractApplicationContext.refresh() - 容器刷新核心方法:
java
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 准备刷新上下文
prepareRefresh();
// 2. 获取 BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. 准备 BeanFactory(设置类加载器、表达式解析器等)
prepareBeanFactory(beanFactory);
try {
// 4. BeanFactory 后置处理(子类扩展点)
postProcessBeanFactory(beanFactory);
// 5. 执行 BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 注册 BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// 7. 初始化国际化资源
initMessageSource();
// 8. 初始化事件广播器
initApplicationEventMulticaster();
// 9. 初始化其他特殊 Bean(子类扩展点)
onRefresh();
// 10. 注册监听器
registerListeners();
// 11. 实例化所有非懒加载的单例 Bean
finishBeanFactoryInitialization(beanFactory);
// 12. 完成刷新,发布事件
finishRefresh();
} catch (BeansException ex) {
// 销毁已创建的单例 Bean
destroyBeans();
// 重置激活标志
cancelRefresh(ex);
throw ex;
} finally {
// 清理缓存
resetCommonCaches();
}
}
}
关键步骤详解:
1. prepareRefresh() - 准备刷新
java
protected void prepareRefresh() {
// 设置启动时间
this.startupDate = System.currentTimeMillis();
// 设置关闭标志为 false
this.closed.set(false);
// 设置激活标志为 true
this.active.set(true);
// 初始化属性源(可被子类覆盖)
initPropertySources();
// 验证必需的属性
getEnvironment().validateRequiredProperties();
// 存储预刷新的监听器
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
} else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// 初始化早期事件集合
this.earlyApplicationEvents = new LinkedHashSet<>();
}
2. obtainFreshBeanFactory() - 获取 BeanFactory
java
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 刷新 BeanFactory
refreshBeanFactory();
// 返回 BeanFactory
return getBeanFactory();
}
// GenericApplicationContext.refreshBeanFactory()
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts");
}
this.beanFactory.setSerializationId(getId());
}
3. invokeBeanFactoryPostProcessors() - 执行 BeanFactory 后置处理器
java
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory,
getBeanFactoryPostProcessors());
// 检测 LoadTimeWeaver
if (beanFactory.getTempClassLoader() == null &&
beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
BeanFactoryPostProcessor 执行顺序:
java
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory,
List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 1. 先执行 BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 1.1 执行手动注册的 BeanDefinitionRegistryPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
}
// 1.2 执行实现了 PriorityOrdered 的 BeanDefinitionRegistryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(
beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
// 1.3 执行实现了 Ordered 的
// 1.4 执行其余的
// ... 省略类似逻辑
// 2. 再执行普通的 BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
}
}
4. finishBeanFactoryInitialization() - 实例化单例 Bean
java
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 1. 初始化类型转换服务
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 2. 冻结配置
beanFactory.freezeConfiguration();
// 3. 实例化所有非懒加载的单例 Bean
beanFactory.preInstantiateSingletons();
}
// DefaultListableBeanFactory.preInstantiateSingletons()
@Override
public void preInstantiateSingletons() throws BeansException {
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 遍历所有 Bean 定义
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非抽象、单例、非懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// 处理 FactoryBean
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
if (factory.isEagerInit()) {
getBean(beanName);
}
}
} else {
// 普通 Bean
getBean(beanName);
}
}
}
// SmartInitializingSingleton 回调
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton =
(SmartInitializingSingleton) singletonInstance;
smartSingleton.afterSingletonsInstantiated();
}
}
}
getBean() 核心流程
java
// AbstractBeanFactory.doGetBean()
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType,
@Nullable Object[] args, boolean typeCheckOnly) {
// 1. 转换 Bean 名称(去除 & 前缀,解析别名)
String beanName = transformedBeanName(name);
Object bean;
// 2. 从缓存获取单例 Bean(三级缓存)
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 3. 获取 Bean 实例(处理 FactoryBean)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// 4. 检查是否存在循环依赖(原型模式)
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 5. 检查父工厂
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
return parentBeanFactory.getBean(name, requiredType);
}
// 6. 标记 Bean 为已创建
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 7. 获取合并后的 Bean 定义
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 8. 先初始化依赖的 Bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
registerDependentBean(dep, beanName);
getBean(dep);
}
}
// 9. 创建 Bean 实例
if (mbd.isSingleton()) {
// 单例
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// 原型
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
// 其他作用域(request、session 等)
String scopeName = mbd.getScope();
Scope scope = this.scopes.get(scopeName);
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
} catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 10. 类型转换
if (requiredType != null && !requiredType.isInstance(bean)) {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
return convertedBean;
}
return (T) bean;
}
1.6 使用示例
基于 XML 配置
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Bean 定义 -->
<bean id="userDao" class="com.example.dao.UserDaoImpl"/>
<!-- 构造器注入 -->
<bean id="userService" class="com.example.service.UserService">
<constructor-arg ref="userDao"/>
</bean>
<!-- Setter 注入 -->
<bean id="orderService" class="com.example.service.OrderService">
<property name="userService" ref="userService"/>
<property name="timeout" value="3000"/>
</bean>
<!-- 集合注入 -->
<bean id="dataSource" class="com.example.DataSource">
<property name="urls">
<list>
<value>jdbc:mysql://localhost:3306/db1</value>
<value>jdbc:mysql://localhost:3306/db2</value>
</list>
</property>
<property name="properties">
<props>
<prop key="username">root</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
</beans>
java
// 使用
public class XmlConfigTest {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.getUser(1L);
}
}
基于注解配置
java
@Configuration
@ComponentScan("com.example")
@EnableAspectJAutoProxy
public class AppConfig {
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("root");
dataSource.setPassword("123456");
return dataSource;
}
@Bean(initMethod = "init", destroyMethod = "close")
@Scope("singleton")
public ConnectionPool connectionPool(DataSource dataSource) {
return new ConnectionPool(dataSource);
}
@Bean
@Primary // 多个同类型 Bean 时,优先使用此 Bean
public UserDao primaryUserDao() {
return new UserDaoImpl();
}
@Bean
@Conditional(WindowsCondition.class) // 条件装配
public FileService windowsFileService() {
return new WindowsFileService();
}
}
java
// 使用
public class AnnotationConfigTest {
public static void main(String[] args) {
ApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = context.getBean(UserService.class);
userService.getUser(1L);
}
}
常用注解
java
// 组件扫描注解
@Component // 通用组件
@Service // 业务层
@Repository // 数据访问层
@Controller // 控制层
@Configuration // 配置类
// 依赖注入注解
@Autowired // 按类型注入
@Qualifier // 指定 Bean 名称
@Resource // JSR-250,按名称注入
@Inject // JSR-330,按类型注入
@Value // 注入配置值
// Bean 定义注解
@Bean // 定义 Bean
@Scope // 作用域
@Lazy // 懒加载
@Primary // 主要候选 Bean
@DependsOn // 依赖关系
// 条件注解
@Conditional // 条件装配
@Profile // 环境配置
@ConditionalOnClass
@ConditionalOnBean
@ConditionalOnProperty
二、Spring AOP 深度解析
2.1 AOP 概述
什么是 AOP
AOP(Aspect-Oriented Programming,面向切面编程) 是一种编程范式,通过预编译方式和运行期动态代理实现程序功能的统一维护。它将横切关注点(Cross-Cutting Concerns)从业务逻辑中分离出来。
横切关注点
业务逻辑:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 用户管理 │ │ 订单管理 │ │ 支付管理 │
└─────────────┘ └─────────────┘ └─────────────┘
↓ ↓ ↓
日志记录 日志记录 日志记录
权限检查 权限检查 权限检查
事务管理 事务管理 事务管理
性能监控 性能监控 性能监控
横切关注点(Cross-Cutting Concerns):
- 日志记录
- 权限检查
- 事务管理
- 性能监控
- 异常处理
- 缓存管理
AOP 的作用
| 作用 | 说明 | 示例 |
|---|---|---|
| 代码复用 | 公共功能抽取到切面 | 日志、事务 |
| 降低耦合 | 业务逻辑与系统服务解耦 | 权限检查 |
| 便于维护 | 集中管理横切关注点 | 统一异常处理 |
| 动态增强 | 运行时动态添加功能 | 性能监控 |
OOP vs AOP
OOP(面向对象编程):
- 关注点:业务实体和行为
- 维度:纵向(继承、封装、多态)
- 适用:核心业务逻辑
AOP(面向切面编程):
- 关注点:横切关注点
- 维度:横向(在多个对象间应用)
- 适用:系统服务(日志、事务等)
两者互补,共同构建完整系统
2.2 AOP 核心概念
核心术语
java
// 1. Aspect(切面)
// 横切关注点的模块化,由切点和通知组成
@Aspect
@Component
public class LoggingAspect {
// ...
}
// 2. Join Point(连接点)
// 程序执行的某个特定位置(方法调用、异常抛出等)
// Spring AOP 仅支持方法级别的连接点
// 3. Pointcut(切点)
// 匹配连接点的表达式,定义在哪里应用通知
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceLayer() {}
// 4. Advice(通知/增强)
// 在切点处执行的代码
@Before("serviceLayer()")
public void logBefore(JoinPoint joinPoint) {
// 前置通知
}
// 5. Target(目标对象)
// 被代理的对象
// 6. Proxy(代理对象)
// AOP 框架创建的对象,包含通知
// 7. Weaving(织入)
// 将切面应用到目标对象的过程
// Spring AOP 使用运行时织入(动态代理)
通知类型
java
@Aspect
@Component
public class AspectDemo {
// 1. @Before - 前置通知
// 在目标方法执行之前执行
@Before("execution(* com.example.service.*.*(..))")
public void before(JoinPoint joinPoint) {
System.out.println("Before: " + joinPoint.getSignature().getName());
}
// 2. @After - 后置通知(最终通知)
// 在目标方法执行之后执行(无论是否抛出异常)
@After("execution(* com.example.service.*.*(..))")
public void after(JoinPoint joinPoint) {
System.out.println("After: " + joinPoint.getSignature().getName());
}
// 3. @AfterReturning - 返回后通知
// 在目标方法正常返回后执行
@AfterReturning(
pointcut = "execution(* com.example.service.*.*(..))",
returning = "result"
)
public void afterReturning(JoinPoint joinPoint, Object result) {
System.out.println("AfterReturning: " + result);
}
// 4. @AfterThrowing - 异常通知
// 在目标方法抛出异常后执行
@AfterThrowing(
pointcut = "execution(* com.example.service.*.*(..))",
throwing = "ex"
)
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
System.out.println("AfterThrowing: " + ex.getMessage());
}
// 5. @Around - 环绕通知
// 包围目标方法,可以控制方法的执行
@Around("execution(* com.example.service.*.*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("Around - Before");
try {
// 执行目标方法
Object result = pjp.proceed();
System.out.println("Around - AfterReturning");
return result;
} catch (Exception ex) {
System.out.println("Around - AfterThrowing");
throw ex;
} finally {
System.out.println("Around - After");
}
}
}
执行顺序:
正常流程:
@Around - Before
↓
@Before
↓
目标方法执行
↓
@Around - AfterReturning
↓
@After
↓
@AfterReturning
异常流程:
@Around - Before
↓
@Before
↓
目标方法执行(抛出异常)
↓
@Around - AfterThrowing
↓
@After
↓
@AfterThrowing
Pointcut 表达式
execution 表达式
java
// 语法:
execution(modifiers? return-type declaring-type?.method-name(param-types) throws?)
// 示例:
@Pointcut("execution(public * com.example.service.*.*(..))")
// ↑ ↑ ↑ ↑ ↑ ↑
// 访问 返回 包名 类 方法 参数
// 修饰符 类型 名 名
// 1. 匹配所有 public 方法
@Pointcut("execution(public * *(..))")
// 2. 匹配所有 set 开头的方法
@Pointcut("execution(* set*(..))")
// 3. 匹配 UserService 的所有方法
@Pointcut("execution(* com.example.service.UserService.*(..))")
// 4. 匹配 service 包下所有类的所有方法
@Pointcut("execution(* com.example.service.*.*(..))")
// 5. 匹配 service 包及子包下所有类的所有方法
@Pointcut("execution(* com.example.service..*.*(..))")
// 6. 匹配第一个参数为 Long 类型的方法
@Pointcut("execution(* *(Long, ..))")
// 7. 匹配返回值为 User 类型的方法
@Pointcut("execution(com.example.entity.User *(..))")
其他切点指示符
java
// 1. within - 匹配指定类型内的方法
@Pointcut("within(com.example.service.*)") // service 包下的类
@Pointcut("within(com.example.service..*)") // service 包及子包
// 2. this - 代理对象是指定类型
@Pointcut("this(com.example.service.UserService)")
// 3. target - 目标对象是指定类型
@Pointcut("target(com.example.service.UserService)")
// 4. args - 参数是指定类型
@Pointcut("args(Long, String)")
// 5. @annotation - 匹配有指定注解的方法
@Pointcut("@annotation(com.example.annotation.Log)")
// 6. @within - 匹配有指定注解的类
@Pointcut("@within(org.springframework.stereotype.Service)")
// 7. @target - 目标对象的类有指定注解
@Pointcut("@target(org.springframework.stereotype.Service)")
// 8. @args - 参数的类有指定注解
@Pointcut("@args(com.example.annotation.Validated)")
// 9. bean - 匹配 Spring Bean 名称
@Pointcut("bean(userService)") // 匹配名为 userService 的 Bean
@Pointcut("bean(*Service)") // 匹配以 Service 结尾的 Bean
组合切点
java
@Aspect
@Component
public class CombinedPointcuts {
// 定义切点
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceLayer() {}
@Pointcut("execution(* com.example.dao.*.*(..))")
public void daoLayer() {}
@Pointcut("@annotation(com.example.annotation.Log)")
public void logAnnotation() {}
// 组合切点
// 1. && - 与
@Pointcut("serviceLayer() && logAnnotation()")
public void serviceWithLog() {}
// 2. || - 或
@Pointcut("serviceLayer() || daoLayer()")
public void serviceOrDao() {}
// 3. ! - 非
@Pointcut("serviceLayer() && !logAnnotation()")
public void serviceWithoutLog() {}
// 使用
@Before("serviceWithLog()")
public void beforeServiceWithLog(JoinPoint joinPoint) {
// ...
}
}
2.3 动态代理原理
JDK 动态代理
适用场景:目标对象实现了接口
实现原理 :java.lang.reflect.Proxy
java
// 1. 定义接口
public interface UserService {
User getUser(Long id);
void saveUser(User user);
}
// 2. 实现类
public class UserServiceImpl implements UserService {
@Override
public User getUser(Long id) {
System.out.println("查询用户: " + id);
return new User(id, "张三");
}
@Override
public void saveUser(User user) {
System.out.println("保存用户: " + user);
}
}
// 3. 创建代理
public class JdkProxyDemo {
public static void main(String[] args) {
UserService target = new UserServiceImpl();
// 创建代理对象
UserService proxy = (UserService) Proxy.newProxyInstance(
target.getClass().getClassLoader(), // 类加载器
target.getClass().getInterfaces(), // 接口数组
new InvocationHandler() { // 调用处理器
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("Before: " + method.getName());
// 执行目标方法
Object result = method.invoke(target, args);
System.out.println("After: " + method.getName());
return result;
}
}
);
// 使用代理
proxy.getUser(1L);
}
}
输出:
Before: getUser
查询用户: 1
After: getUser
JDK 代理源码分析:
java
// Proxy.newProxyInstance()
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h) {
Objects.requireNonNull(h);
// 1. 克隆接口数组
final Class<?>[] intfs = interfaces.clone();
// 2. 获取或生成代理类
Class<?> cl = getProxyClass0(loader, intfs);
// 3. 获取构造器
final Constructor<?> cons = cl.getConstructor(constructorParams);
// 4. 创建代理实例
return cons.newInstance(new Object[]{h});
}
// 生成的代理类(反编译后)
public final class $Proxy0 extends Proxy implements UserService {
private static Method m3; // getUser 方法
private static Method m4; // saveUser 方法
static {
try {
m3 = Class.forName("com.example.UserService")
.getMethod("getUser", new Class[]{Long.class});
m4 = Class.forName("com.example.UserService")
.getMethod("saveUser", new Class[]{User.class});
} catch (Exception e) {
throw new NoSuchMethodError(e.getMessage());
}
}
public $Proxy0(InvocationHandler h) {
super(h);
}
// 实现接口方法
public final User getUser(Long id) {
try {
// 调用 InvocationHandler.invoke()
return (User) super.h.invoke(this, m3, new Object[]{id});
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
public final void saveUser(User user) {
try {
super.h.invoke(this, m4, new Object[]{user});
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
}
CGLIB 动态代理
适用场景:目标对象没有实现接口
实现原理:通过字节码技术生成目标类的子类
java
// 1. 目标类(无接口)
public class OrderService {
public Order getOrder(Long id) {
System.out.println("查询订单: " + id);
return new Order(id, "订单001");
}
}
// 2. 创建代理
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class CglibProxyDemo {
public static void main(String[] args) {
// 创建 Enhancer
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(OrderService.class);
// 设置回调
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("Before: " + method.getName());
// 调用父类方法
Object result = proxy.invokeSuper(obj, args);
System.out.println("After: " + method.getName());
return result;
}
});
// 创建代理对象
OrderService proxy = (OrderService) enhancer.create();
// 使用代理
proxy.getOrder(1L);
}
}
输出:
Before: getOrder
查询订单: 1
After: getOrder
CGLIB 生成的代理类:
java
// 简化的代理类结构
public class OrderService$$EnhancerByCGLIB$$12345 extends OrderService {
private MethodInterceptor CGLIB$CALLBACK_0;
// 原始方法的引用
private static final Method CGLIB$getOrder$0$Method;
private static final MethodProxy CGLIB$getOrder$0$Proxy;
static {
// 初始化方法引用
CGLIB$getOrder$0$Method =
Class.forName("com.example.OrderService")
.getDeclaredMethod("getOrder", new Class[]{Long.class});
CGLIB$getOrder$0$Proxy =
MethodProxy.create(OrderService.class,
OrderService$$EnhancerByCGLIB$$12345.class,
"(Ljava/lang/Long;)Lcom/example/Order;",
"getOrder", "CGLIB$getOrder$0");
}
@Override
public Order getOrder(Long id) {
MethodInterceptor callback = this.CGLIB$CALLBACK_0;
if (callback == null) {
CGLIB$BIND_CALLBACKS(this);
callback = this.CGLIB$CALLBACK_0;
}
if (callback != null) {
// 调用拦截器
return (Order) callback.intercept(this,
CGLIB$getOrder$0$Method,
new Object[]{id},
CGLIB$getOrder$0$Proxy);
} else {
// 直接调用父类方法
return super.getOrder(id);
}
}
// 生成的方法,用于调用父类原始方法
final Order CGLIB$getOrder$0(Long id) {
return super.getOrder(id);
}
}
JDK vs CGLIB 对比
| 维度 | JDK 动态代理 | CGLIB 动态代理 |
|---|---|---|
| 实现方式 | 基于接口,使用反射 | 基于继承,使用字节码 |
| 要求 | 目标对象必须实现接口 | 目标对象不能是 final 类 |
| 性能 | 调用稍慢(反射) | 调用较快(直接调用) |
| 创建速度 | 较快 | 较慢(生成字节码) |
| Spring 选择 | 实现接口时优先使用 | 无接口时使用 |
| 代理对象 | 实现相同接口 | 继承目标类 |
Spring AOP 代理选择策略:
java
// DefaultAopProxyFactory.createAopProxy()
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || // 优化标志
config.isProxyTargetClass() || // 强制 CGLIB
hasNoUserSuppliedProxyInterfaces(config)) { // 无接口
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class");
}
// 接口或 Proxy 类,使用 JDK 代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 使用 CGLIB 代理
return new ObjenesisCglibAopProxy(config);
} else {
// 使用 JDK 代理
return new JdkDynamicAopProxy(config);
}
}
2.4 源码分析
AOP 自动代理原理
@EnableAspectJAutoProxy 注解:
java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class) // 关键:导入注册器
public @interface EnableAspectJAutoProxy {
// 是否强制使用 CGLIB
boolean proxyTargetClass() default false;
// 是否暴露代理对象到 AopContext
boolean exposeProxy() default false;
}
AspectJAutoProxyRegistrar - 注册 Bean 定义:
java
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
// 注册 AnnotationAwareAspectJAutoProxyCreator
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
// 处理 @EnableAspectJAutoProxy 的属性
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata,
EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
AnnotationAwareAspectJAutoProxyCreator 继承体系:
Object
↓
ProxyConfig
↓
ProxyProcessorSupport
↓
AbstractAutoProxyCreator (实现 BeanPostProcessor)
↓
AbstractAdvisorAutoProxyCreator
↓
AspectJAwareAdvisorAutoProxyCreator
↓
AnnotationAwareAspectJAutoProxyCreator
AbstractAutoProxyCreator - 核心自动代理创建器:
java
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
// BeanPostProcessor 后置处理方法
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 如果不是提前代理的 Bean
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 如果需要代理,则创建代理对象
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
// 包装(创建代理)
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 1. 已经处理过
if (StringUtils.hasLength(beanName) &&
this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 2. 不需要增强
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 3. 是基础设施类或需要跳过
if (isInfrastructureClass(bean.getClass()) ||
shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 4. 获取适用于此 Bean 的增强器(Advisor)
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(
bean.getClass(), beanName, null);
// 5. 如果有增强器,创建代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors,
new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
创建代理对象:
java
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
// 1. 创建 ProxyFactory
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 2. 决定使用 JDK 代理还是 CGLIB 代理
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 3. 构建 Advisor 数组
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
// 4. 自定义 ProxyFactory(扩展点)
customizeProxyFactory(proxyFactory);
// 5. 创建代理
return proxyFactory.getProxy(getProxyClassLoader());
}
// ProxyFactory.getProxy()
public Object getProxy(@Nullable ClassLoader classLoader) {
// 创建 AopProxy 并获取代理对象
return createAopProxy().getProxy(classLoader);
}
查找匹配的 Advisor
AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean():
java
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName,
@Nullable TargetSource targetSource) {
// 查找符合条件的 Advisor
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 1. 查找所有候选的 Advisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 2. 筛选适用于当前 Bean 的 Advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors,
beanClass, beanName);
// 3. 扩展 Advisor 列表
extendAdvisors(eligibleAdvisors);
// 4. 排序
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
查找候选 Advisor:
java
// AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()
@Override
protected List<Advisor> findCandidateAdvisors() {
// 1. 调用父类方法,查找实现了 Advisor 接口的 Bean
List<Advisor> advisors = super.findCandidateAdvisors();
// 2. 从 @Aspect 注解的类中构建 Advisor
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
// BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors()
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 1. 获取所有 Bean 名称
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// 2. 判断是否为切面类(有 @Aspect 注解)
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 3. 解析切面类中的 Advisor
List<Advisor> classAdvisors =
this.advisorFactory.getAdvisors(factory);
this.advisorsCache.put(beanName, classAdvisors);
advisors.addAll(classAdvisors);
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
// 从缓存获取
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
}
return advisors;
}
从切面类解析 Advisor:
java
// ReflectiveAspectJAdvisorFactory.getAdvisors()
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
List<Advisor> advisors = new ArrayList<>();
// 1. 获取切面类的所有方法(不包括 @Pointcut 方法)
for (Method method : getAdvisorMethods(aspectClass)) {
// 2. 为每个方法创建 Advisor
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory,
advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
@Override
public Advisor getAdvisor(Method candidateAdviceMethod,
MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
// 1. 获取切点表达式
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
// 2. 创建 Advisor(包含切点和通知)
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut,
candidateAdviceMethod, this, aspectInstanceFactory,
declarationOrderInAspect, aspectName);
}
代理方法调用
JdkDynamicAopProxy.invoke():
java
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
// 1. 处理 equals、hashCode 等方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
} else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
// 2. 设置代理上下文(如果需要)
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 3. 获取目标对象
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 4. 获取拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(
method, targetClass);
// 5. 如果没有拦截器,直接调用目标方法
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
// 6. 创建方法调用对象
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args,
targetClass, chain);
// 7. 执行拦截器链
retVal = invocation.proceed();
}
// 8. 处理返回值
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy)) {
retVal = proxy;
}
return retVal;
} finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
拦截器链执行:
java
// ReflectiveMethodInvocation.proceed()
@Override
public Object proceed() throws Throwable {
// 1. 执行完所有拦截器,调用目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 2. 获取下一个拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// 3. 动态方法匹配器
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
} else {
// 不匹配,跳过此拦截器
return proceed();
}
} else {
// 4. 执行拦截器
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
拦截器示例 - AspectJAfterAdvice:
java
public class AspectJAfterAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
// 先执行后续拦截器和目标方法
return mi.proceed();
} finally {
// 最后执行通知方法(无论是否抛出异常)
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
}
拦截器链执行流程:
proxy.method()
↓
JdkDynamicAopProxy.invoke()
↓
ReflectiveMethodInvocation.proceed()
↓
拦截器1.invoke() → proceed()
↓
拦截器2.invoke() → proceed()
↓
拦截器3.invoke() → proceed()
↓
目标方法执行
↓
返回 ← 拦截器3
↓
返回 ← 拦截器2
↓
返回 ← 拦截器1
↓
返回 ← invoke()
2.5 使用示例
基于注解的 AOP
java
// 1. 自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String value() default "";
}
// 2. 切面类
@Aspect
@Component
@Slf4j
public class LoggingAspect {
// 定义切点
@Pointcut("@annotation(com.example.annotation.Log)")
public void logPointcut() {}
// 环绕通知
@Around("logPointcut() && @annotation(logAnnotation)")
public Object logAround(ProceedingJoinPoint pjp, Log logAnnotation) throws Throwable {
// 获取方法信息
String className = pjp.getTarget().getClass().getName();
String methodName = pjp.getSignature().getName();
Object[] args = pjp.getArgs();
// 记录开始时间
long startTime = System.currentTimeMillis();
log.info("开始执行: {}.{}(), 参数: {}, 描述: {}",
className, methodName, args, logAnnotation.value());
Object result = null;
try {
// 执行目标方法
result = pjp.proceed();
// 记录执行时间
long elapsedTime = System.currentTimeMillis() - startTime;
log.info("执行成功: {}.{}(), 耗时: {}ms, 返回值: {}",
className, methodName, elapsedTime, result);
return result;
} catch (Exception ex) {
log.error("执行异常: {}.{}(), 异常信息: {}",
className, methodName, ex.getMessage(), ex);
throw ex;
}
}
}
// 3. 使用
@Service
public class UserService {
@Log("获取用户信息")
public User getUser(Long id) {
// 业务逻辑
return new User(id, "张三");
}
@Log("保存用户")
public void saveUser(User user) {
// 业务逻辑
}
}
性能监控切面
java
@Aspect
@Component
public class PerformanceAspect {
private static final long SLOW_METHOD_THRESHOLD = 1000; // 1秒
@Around("execution(* com.example.service..*.*(..))")
public Object monitorPerformance(ProceedingJoinPoint pjp) throws Throwable {
MethodSignature signature = (MethodSignature) pjp.getSignature();
String methodName = signature.getDeclaringTypeName() + "." + signature.getName();
long startTime = System.nanoTime();
try {
Object result = pjp.proceed();
return result;
} finally {
long endTime = System.nanoTime();
long duration = (endTime - startTime) / 1_000_000; // 转换为毫秒
if (duration > SLOW_METHOD_THRESHOLD) {
System.err.printf("慢方法警告: %s 执行耗时 %dms%n", methodName, duration);
} else {
System.out.printf("方法: %s 执行耗时 %dms%n", methodName, duration);
}
}
}
}
权限校验切面
java
// 1. 权限注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresPermission {
String[] value(); // 需要的权限
}
// 2. 切面
@Aspect
@Component
public class PermissionAspect {
@Autowired
private PermissionService permissionService;
@Before("@annotation(requiresPermission)")
public void checkPermission(JoinPoint joinPoint, RequiresPermission requiresPermission) {
// 获取当前用户
User currentUser = getCurrentUser();
// 获取需要的权限
String[] permissions = requiresPermission.value();
// 检查权限
for (String permission : permissions) {
if (!permissionService.hasPermission(currentUser, permission)) {
throw new PermissionDeniedException(
"用户没有权限: " + permission);
}
}
}
private User getCurrentUser() {
// 从 ThreadLocal 或 SecurityContext 获取当前用户
return UserContext.getCurrentUser();
}
}
// 3. 使用
@Service
public class OrderService {
@RequiresPermission({"order:delete"})
public void deleteOrder(Long orderId) {
// 删除订单
}
}
异常处理切面
java
@Aspect
@Component
@Slf4j
public class ExceptionHandlingAspect {
@AfterThrowing(
pointcut = "execution(* com.example.service..*.*(..))",
throwing = "ex"
)
public void handleException(JoinPoint joinPoint, Exception ex) {
String methodName = joinPoint.getSignature().toShortString();
Object[] args = joinPoint.getArgs();
log.error("方法 {} 执行异常, 参数: {}", methodName, args, ex);
// 可以在这里进行异常统计、告警等
if (ex instanceof BusinessException) {
// 业务异常处理
handleBusinessException((BusinessException) ex);
} else {
// 系统异常处理
handleSystemException(ex);
}
}
private void handleBusinessException(BusinessException ex) {
// 业务异常处理逻辑
}
private void handleSystemException(Exception ex) {
// 系统异常处理逻辑(如发送告警)
}
}
事务管理切面
java
// Spring 已经提供了 @Transactional,这里演示自定义实现
@Aspect
@Component
public class TransactionAspect {
@Autowired
private TransactionManager transactionManager;
@Around("@annotation(org.springframework.transaction.annotation.Transactional)")
public Object manageTransaction(ProceedingJoinPoint pjp) throws Throwable {
TransactionStatus status = transactionManager.getTransaction(
new DefaultTransactionDefinition());
try {
// 执行业务方法
Object result = pjp.proceed();
// 提交事务
transactionManager.commit(status);
return result;
} catch (Exception ex) {
// 回滚事务
transactionManager.rollback(status);
throw ex;
}
}
}
缓存切面
java
@Aspect
@Component
public class CachingAspect {
@Autowired
private CacheManager cacheManager;
@Around("@annotation(cacheable)")
public Object cache(ProceedingJoinPoint pjp, Cacheable cacheable) throws Throwable {
String cacheName = cacheable.value();
String key = generateKey(pjp);
// 从缓存获取
Object cachedValue = cacheManager.get(cacheName, key);
if (cachedValue != null) {
System.out.println("从缓存获取: " + key);
return cachedValue;
}
// 执行方法
Object result = pjp.proceed();
// 放入缓存
if (result != null) {
cacheManager.put(cacheName, key, result);
}
return result;
}
private String generateKey(ProceedingJoinPoint pjp) {
StringBuilder key = new StringBuilder();
key.append(pjp.getSignature().toShortString());
for (Object arg : pjp.getArgs()) {
key.append(":").append(arg);
}
return key.toString();
}
}
// 使用
@Service
public class ProductService {
@Cacheable("products")
public Product getProduct(Long id) {
// 从数据库查询
return productDao.findById(id);
}
}
三、IOC 与 AOP 结合
3.1 结合原理
IOC 容器负责管理 Bean 的生命周期:
1. 实例化 Bean
2. 设置属性(依赖注入)
3. 初始化 Bean
↓
BeanPostProcessor.postProcessAfterInitialization()
↓
AOP 在这里创建代理对象
↓
4. Bean 使用
5. 销毁
3.2 完整示例
java
// 1. 配置类
@Configuration
@ComponentScan("com.example")
@EnableAspectJAutoProxy
public class AppConfig {
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("root");
dataSource.setPassword("123456");
return dataSource;
}
}
// 2. DAO 层
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public User findById(Long id) {
return jdbcTemplate.queryForObject(
"SELECT * FROM user WHERE id = ?",
new BeanPropertyRowMapper<>(User.class),
id
);
}
}
// 3. Service 层
@Service
public class UserService {
@Autowired
private UserDao userDao;
@Log("查询用户")
@Transactional
public User getUser(Long id) {
return userDao.findById(id);
}
@Log("保存用户")
@Transactional
@RequiresPermission("user:save")
public void saveUser(User user) {
// 保存逻辑
}
}
// 4. 日志切面
@Aspect
@Component
public class LoggingAspect {
@Around("@annotation(log)")
public Object logAround(ProceedingJoinPoint pjp, Log log) throws Throwable {
System.out.println("日志: " + log.value());
return pjp.proceed();
}
}
// 5. 权限切面
@Aspect
@Component
@Order(1) // 优先级高于日志切面
public class PermissionAspect {
@Before("@annotation(requiresPermission)")
public void checkPermission(RequiresPermission requiresPermission) {
System.out.println("权限检查: " + Arrays.toString(requiresPermission.value()));
}
}
// 6. 测试
public class Application {
public static void main(String[] args) {
ApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = context.getBean(UserService.class);
// 调用会触发:权限检查 → 日志记录 → 事务管理 → 实际方法
userService.saveUser(new User(1L, "张三"));
}
}
3.3 多切面执行顺序
java
// 使用 @Order 或实现 Ordered 接口控制顺序
@Aspect
@Component
@Order(1) // 数字越小优先级越高
public class FirstAspect {
@Before("execution(* com.example.service.*.*(..))")
public void before() {
System.out.println("FirstAspect - Before");
}
@After("execution(* com.example.service.*.*(..))")
public void after() {
System.out.println("FirstAspect - After");
}
}
@Aspect
@Component
@Order(2)
public class SecondAspect {
@Before("execution(* com.example.service.*.*(..))")
public void before() {
System.out.println("SecondAspect - Before");
}
@After("execution(* com.example.service.*.*(..))")
public void after() {
System.out.println("SecondAspect - After");
}
}
// 执行顺序:
// FirstAspect - Before
// SecondAspect - Before
// 目标方法
// SecondAspect - After
// FirstAspect - After
四、高级特性
4.1 自定义 BeanPostProcessor
java
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("Before Initialization: " + beanName);
// 可以对 Bean 进行处理
if (bean instanceof UserService) {
// 自定义逻辑
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("After Initialization: " + beanName);
// 可以返回代理对象
return bean;
}
}
4.2 自定义 BeanFactoryPostProcessor
java
@Component
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
System.out.println("BeanFactory 后置处理");
// 修改 Bean 定义
String[] beanNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
// 例如:修改所有 Bean 为懒加载
if ("userService".equals(beanName)) {
beanDefinition.setLazyInit(true);
}
}
}
}
4.3 Introduction(引入)
java
// 为现有类添加新接口的实现
// 1. 定义接口
public interface Lockable {
void lock();
void unlock();
boolean isLocked();
}
// 2. 接口实现
public class LockableImpl implements Lockable {
private boolean locked;
@Override
public void lock() {
this.locked = true;
}
@Override
public void unlock() {
this.locked = false;
}
@Override
public boolean isLocked() {
return this.locked;
}
}
// 3. 切面
@Aspect
@Component
public class LockableAspect {
@DeclareParents(
value = "com.example.service.*+", // 目标类
defaultImpl = LockableImpl.class // 默认实现
)
public static Lockable lockable;
}
// 4. 使用
UserService userService = context.getBean(UserService.class);
// UserService 现在也实现了 Lockable 接口
Lockable lockable = (Lockable) userService;
lockable.lock();
System.out.println("Is locked: " + lockable.isLocked());
4.4 获取代理对象
java
@Service
public class SelfInvocationService {
@Transactional
public void methodA() {
// 直接调用不会触发事务
// this.methodB();
// 通过代理对象调用,才会触发事务
((SelfInvocationService) AopContext.currentProxy()).methodB();
}
@Transactional
public void methodB() {
// 业务逻辑
}
}
// 需要配置 exposeProxy = true
@EnableAspectJAutoProxy(exposeProxy = true)
五、最佳实践
5.1 IOC 最佳实践
java
// 1. 优先使用构造器注入
@Service
public class UserService {
private final UserDao userDao;
private final EmailService emailService;
// 单个构造器可省略 @Autowired
public UserService(UserDao userDao, EmailService emailService) {
this.userDao = userDao;
this.emailService = emailService;
}
}
// 2. 使用 @Primary 解决多实现冲突
@Bean
@Primary
public UserDao primaryUserDao() {
return new MysqlUserDao();
}
@Bean
public UserDao redisUserDao() {
return new RedisUserDao();
}
// 3. 使用 @Qualifier 指定具体实现
@Service
public class UserService {
@Autowired
@Qualifier("redisUserDao")
private UserDao userDao;
}
// 4. 避免循环依赖
// 使用 @Lazy 延迟注入
@Service
public class A {
@Autowired
@Lazy
private B b;
}
// 5. 合理使用作用域
@Service
@Scope("prototype") // 原型模式,每次获取都创建新实例
public class StatefulService {
private int counter;
}
5.2 AOP 最佳实践
java
// 1. 切点复用
@Aspect
@Component
public class CommonPointcuts {
@Pointcut("execution(* com.example.service..*.*(..))")
public void serviceLayer() {}
@Pointcut("execution(* com.example.dao..*.*(..))")
public void daoLayer() {}
@Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)")
public void transactionalMethod() {}
}
// 其他切面引用
@Aspect
@Component
public class LoggingAspect {
@Before("com.example.aspect.CommonPointcuts.serviceLayer()")
public void logServiceMethod() {
// ...
}
}
// 2. 使用 @Around 代替多个通知
// 不推荐
@Before("serviceLayer()")
public void before() {}
@AfterReturning("serviceLayer()")
public void afterReturning() {}
@AfterThrowing("serviceLayer()")
public void afterThrowing() {}
// 推荐
@Around("serviceLayer()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
try {
// Before logic
Object result = pjp.proceed();
// AfterReturning logic
return result;
} catch (Exception ex) {
// AfterThrowing logic
throw ex;
}
}
// 3. 合理设置切面优先级
@Aspect
@Component
@Order(Ordered.HIGHEST_PRECEDENCE) // 最高优先级
public class SecurityAspect {}
@Aspect
@Component
@Order(1)
public class TransactionAspect {}
@Aspect
@Component
@Order(2)
public class LoggingAspect {}
// 4. 避免在切面中修改参数
@Before("serviceLayer()")
public void before(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
// 避免修改 args
}
// 5. 性能考虑
// 避免过于宽泛的切点表达式
@Pointcut("execution(* *(..))") // 不推荐:匹配所有方法
@Pointcut("execution(* com.example.service.*.*(..))") // 推荐:精确匹配