You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中Proxy与Aspect代码正确性咨询(首次使用AOP)

Spring AOP 代码问题解答

问题描述

我是首次使用Spring Boot的AOP技术,正在学习Proxy与Aspect的用法,目前编写了相关代码,但不确定代码是否正确,尤其疑惑切面是否应该指向代理方法,希望得到解答。

现有代码

代理类代码(ProxyOggetto)

package local.luddel;

import org.springframework.stereotype.Component;

@Component
public class ProxyOggetto {
    
    private InterfacciaOggetto interfacciaOggetto;

    public ProxyOggetto(InterfacciaOggetto interfacciaOggetto) {
        super();
        this.interfacciaOggetto = interfacciaOggetto;
    }
    
    
    public void getEccociOggetto() {
        System.out.println("Sono nel proxy");
        interfacciaOggetto.eccoci();
    }
    public void getCiaoOggetto() {
        System.out.println("Sono nel proxy");
        interfacciaOggetto.ciao();
    }
}

切面类代码(MyAspect)

package local.luddel;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyAspect {
    @Before(value = "execution(* local.luddel.ProxyOggetto.getEccociOggetto())")
    public void beforeEccoci() {
        System.out.println("Sono in aspect");
    }
}

配置类代码(ConfigBean)

package local.luddel;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;


@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class ConfigBean {
    
    @Bean(value = "oggetto")
    public Oggetto getOggetto() {
        return new Oggetto();
    }
    
    @Bean(value = "myAspect")
    public MyAspect getMyAspect() {
        return new MyAspect();
    }
    
    @Bean(value = "service")
    public Servizio getServizio(){
        return new Servizio();
    }
    @Bean(value = "proxy")
    public ProxyOggetto getProxyOggetto() {
        return new ProxyOggetto(getOggetto());
    }

}

主类代码(Main)

package local.luddel;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {

    public static void main(String[] args) {
        myBeanOggetto();
    }

    static public void myBeanOggetto() {
        ApplicationContext applicationContext = new
AnnotationConfigApplicationContext(ConfigBean.class);
        ProxyOggetto proxyOggetto = applicationContext.getBean("proxy", ProxyOggetto.class);
        proxyOggetto.getEccociOggetto();
    }
    
}

代码分析与解答

核心误区澄清

你现在手动编写的ProxyOggetto是静态代理类,而Spring AOP的核心是动态代理——Spring会自动为被切面切入的Bean生成代理对象,完全不需要你手动编写代理类。你的写法虽然能运行,但违背了Spring AOP的设计初衷,也增加了不必要的代码复杂度。

关于切面指向代理方法的疑问

切面可以指向代理方法(比如你现在切ProxyOggetto.getEccociOggetto()),运行时会按以下顺序执行:

  1. 执行Aspect的beforeEccoci()方法
  2. 执行ProxyOggetto.getEccociOggetto()方法
  3. 调用目标对象Oggetto.eccoci()方法

但这种写法完全没必要,Spring AOP可以直接把切面切入到目标对象的方法上,自动帮你完成代理逻辑。

现有代码的问题

  1. Bean重复定义:ProxyOggetto类加了@Component,同时ConfigBean里又用@Bean注册了名为proxy的实例,这会导致Spring容器中存在两个ProxyOggetto实例(一个是ComponentScan扫描生成的proxyOggetto,另一个是@Bean定义的proxy),可能引发依赖注入冲突。
  2. 冗余代码:手动编写的静态代理类完全多余,Spring AOP的动态代理可以替代这个逻辑。

优化方案

  1. 删除手动代理类:直接移除ProxyOggetto类,不需要手动实现代理逻辑。
  2. 修改切面切入点:把切面直接切入到目标对象Oggetto的方法上,修改MyAspect的@Before注解:
    @Before(value = "execution(* local.luddel.Oggetto.eccoci())")
    public void beforeEccoci() {
        System.out.println("Sono in aspect");
    }
    
  3. 清理配置类:删除ConfigBean中getProxyOggetto()的@Bean定义,避免Bean重复。
  4. 简化主类调用:直接从容器获取Oggetto实例并调用方法,Spring会自动生成代理:
    static public void myBeanOggetto() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ConfigBean.class);
        Oggetto oggetto = applicationContext.getBean("oggetto", Oggetto.class);
        oggetto.eccoci();
    }
    

优化后运行效果

执行Main类后,控制台会输出:

Sono in aspect
// Oggetto.eccoci()方法的输出内容

内容的提问来源于stack exchange,提问作者Ludovico Deledda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 20:35:08