Spring IOC 与 AOP 核心原理深度解析

一、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.*.*(..))")  // 推荐:精确匹配
相关推荐
卿雪6 小时前
Redis 线程模型:Redis为什么这么快?Redis为什么引入多线程?
java·数据库·redis·sql·mysql·缓存·golang
lkbhua莱克瓦246 小时前
IO流练习(修改文件中的数据)
java·windows·学习方法·io流·java练习题·io流练习
老华带你飞6 小时前
汽车销售|汽车报价|基于Java汽车销售系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·后端·汽车
西岭千秋雪_7 小时前
MySQL集群搭建
java·数据库·分布式·mysql
小马爱打代码7 小时前
Spring AI:文生视频 - wanx2.1-i2v-plus
java·人工智能·spring
华仔啊7 小时前
RebbitMQ 入门教程看这一篇就够了
java·后端·rabbitmq
象象翔7 小时前
AI+若依(实战篇)
java·人工智能·spring boot·spring
CHANG_THE_WORLD7 小时前
C++ vs Python 参数传递方式对比
java·c++·python
talenteddriver7 小时前
java: 4种API 参数传递方式
java·开发语言