最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring AOP底層源碼深度解析之從動(dòng)態(tài)代理到注解實(shí)現(xiàn)的完整架構(gòu)

 更新時(shí)間:2026年01月15日 10:19:24   作者:alonewolf_99  
這篇文章詳細(xì)介紹了Spring AOP的核心概念、實(shí)現(xiàn)方式、配置方法以及高級(jí)特性,從動(dòng)態(tài)代理基礎(chǔ)到性能優(yōu)化,全面涵蓋了Spring AOP的各個(gè)方面,幫助開(kāi)發(fā)者深入理解并有效地應(yīng)用Spring AOP,感興趣的朋友跟隨小編一起看看吧

一、動(dòng)態(tài)代理基礎(chǔ):Spring AOP的基石

1.1 代理模式的核心思想

代理模式的本質(zhì)是:為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。在Spring AOP中,我們通過(guò)代理模式來(lái)增強(qiáng)目標(biāo)對(duì)象的方法。

1.2 JDK動(dòng)態(tài)代理與CGLIB對(duì)比

1.2.1 CGLIB動(dòng)態(tài)代理示例

public class UserService {
    public void test() {
        System.out.println("test...");
    }
}
// CGLIB動(dòng)態(tài)代理
UserService target = new UserService();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback(new MethodInterceptor() {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, 
                           MethodProxy proxy) throws Throwable {
        System.out.println("before...");
        Object result = proxy.invoke(target, args);
        System.out.println("after...");
        return result;
    }
});
UserService userService = (UserService) enhancer.create();
userService.test();

CGLIB特點(diǎn)

  • 基于繼承實(shí)現(xiàn),代理類(lèi)是目標(biāo)類(lèi)的子類(lèi)
  • 不需要目標(biāo)類(lèi)實(shí)現(xiàn)接口
  • 直接操作字節(jié)碼,性能相對(duì)較高

1.2.2 JDK動(dòng)態(tài)代理示例

public interface UserInterface {
    void test();
}
public class UserService implements UserInterface {
    public void test() {
        System.out.println("test...");
    }
}
// JDK動(dòng)態(tài)代理
UserService target = new UserService();
UserInterface proxy = (UserInterface) Proxy.newProxyInstance(
    UserService.class.getClassLoader(),
    new Class[]{UserInterface.class},
    new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) 
                throws Throwable {
            System.out.println("before...");
            Object result = method.invoke(target, args);
            System.out.println("after...");
            return result;
        }
    }
);
proxy.test();

JDK動(dòng)態(tài)代理特點(diǎn)

  • 基于接口實(shí)現(xiàn)
  • 只能代理實(shí)現(xiàn)了接口的類(lèi)
  • 使用反射機(jī)制,性能相對(duì)較低

1.3 Spring的選擇策略

Spring通過(guò)ProxyFactory統(tǒng)一了兩種動(dòng)態(tài)代理技術(shù)的使用,并根據(jù)以下規(guī)則自動(dòng)選擇:

// ProxyFactory選擇代理類(lèi)型的邏輯
if (config.isOptimize() || config.isProxyTargetClass() || 
    hasNoUserSuppliedProxyInterfaces(config)) {
    Class<?> targetClass = config.getTargetClass();
    if (targetClass == null) {
        throw new AopConfigException("TargetSource cannot determine target class");
    }
    // 目標(biāo)類(lèi)是接口,使用JDK動(dòng)態(tài)代理
    if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
        return new JdkDynamicAopProxy(config);
    }
    // 否則使用CGLIB
    return new ObjenesisCglibAopProxy(config);
} else {
    // 使用JDK動(dòng)態(tài)代理
    return new JdkDynamicAopProxy(config);
}

選擇規(guī)則總結(jié)

  • optimize為true → CGLIB
  • proxyTargetClass為true → CGLIB
  • 目標(biāo)類(lèi)沒(méi)有實(shí)現(xiàn)接口 → CGLIB
  • 目標(biāo)類(lèi)是接口或已經(jīng)是代理類(lèi) → JDK動(dòng)態(tài)代理
  • 其他情況 → JDK動(dòng)態(tài)代理

二、Spring AOP核心概念詳解

2.1 ProxyFactory:統(tǒng)一的代理工廠

ProxyFactory是Spring提供的統(tǒng)一代理創(chuàng)建工廠,它屏蔽了底層動(dòng)態(tài)代理技術(shù)的差異:

UserService target = new UserService();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvice(new MethodInterceptor() {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("before...");
        Object result = invocation.proceed();
        System.out.println("after...");
        return result;
    }
});
UserInterface userService = (UserInterface) proxyFactory.getProxy();
userService.test();

2.2 Advice:通知的類(lèi)型

Spring AOP提供了五種類(lèi)型的通知,對(duì)應(yīng)AspectJ的五個(gè)注解:

通知類(lèi)型對(duì)應(yīng)注解執(zhí)行時(shí)機(jī)
Before Advice@Before方法執(zhí)行前
After Returning Advice@AfterReturning方法正常返回后
After Throwing Advice@AfterThrowing方法拋出異常后
After (Finally) Advice@After方法執(zhí)行后(finally)
Around Advice@Around方法執(zhí)行前后(最強(qiáng)大)

Around Advice示例

@Around("execution(* com.example.service.*.*(..))")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
    // 方法執(zhí)行前邏輯
    System.out.println("Before method: " + joinPoint.getSignature().getName());
    try {
        // 執(zhí)行目標(biāo)方法
        Object result = joinPoint.proceed();
        // 方法正常返回后邏輯
        System.out.println("After method returning");
        return result;
    } catch (Exception e) {
        // 方法拋出異常后邏輯
        System.out.println("After method throwing: " + e.getMessage());
        throw e;
    } finally {
        // 方法執(zhí)行后邏輯(一定會(huì)執(zhí)行)
        System.out.println("After method (finally)");
    }
}

2.3 Advisor:切面 = 切點(diǎn) + 通知

Advisor是Spring AOP的核心概念,它將Pointcut(切點(diǎn))和Advice(通知)組合在一起:

UserService target = new UserService();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvisor(new PointcutAdvisor() {
    @Override
    public Pointcut getPointcut() {
        // 定義切點(diǎn):只匹配名為"testAbc"的方法
        return new StaticMethodMatcherPointcut() {
            @Override
            public boolean matches(Method method, Class<?> targetClass) {
                return method.getName().equals("testAbc");
            }
        };
    }
    @Override
    public Advice getAdvice() {
        // 定義通知邏輯
        return new MethodInterceptor() {
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("before...");
                Object result = invocation.proceed();
                System.out.println("after...");
                return result;
            }
        };
    }
    @Override
    public boolean isPerInstance() {
        return false;
    }
});

三、Spring AOP的三種配置方式

3.1 ProxyFactoryBean:工廠Bean方式

@Configuration
public class AopConfig {
    @Bean
    public MethodInterceptor zhouyuAroundAdvice() {
        return new MethodInterceptor() {
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("before...");
                Object result = invocation.proceed();
                System.out.println("after...");
                return result;
            }
        };
    }
    @Bean
    public ProxyFactoryBean userService() {
        UserService userService = new UserService();
        ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
        proxyFactoryBean.setTarget(userService);
        proxyFactoryBean.setInterceptorNames("zhouyuAroundAdvice");
        return proxyFactoryBean;
    }
}

特點(diǎn)

  • 基于FactoryBean機(jī)制
  • 可以針對(duì)單個(gè)Bean進(jìn)行AOP配置
  • 支持通過(guò)名稱(chēng)引用已定義的Advice

3.2 BeanNameAutoProxyCreator:按Bean名稱(chēng)匹配

@Bean
public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
    BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator();
    // 支持通配符匹配
    creator.setBeanNames("userSe*");
    creator.setInterceptorNames("zhouyuAroundAdvice");
    creator.setProxyTargetClass(true); // 強(qiáng)制使用CGLIB
    return creator;
}

特點(diǎn)

  • 批量配置,支持通配符
  • 只能根據(jù)Bean名稱(chēng)匹配
  • 配置簡(jiǎn)單,但不靈活

3.3 DefaultAdvisorAutoProxyCreator:自動(dòng)代理創(chuàng)建器

@Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor() {
    NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
    pointcut.addMethodName("test");
    DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
    advisor.setPointcut(pointcut);
    advisor.setAdvice(new ZhouyuAfterReturningAdvice());
    return advisor;
}
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
    return new DefaultAdvisorAutoProxyCreator();
}

特點(diǎn)

  • 自動(dòng)掃描所有Advisor
  • 根據(jù)Pointcut匹配決定是否創(chuàng)建代理
  • 最靈活,功能最強(qiáng)大

四、注解驅(qū)動(dòng)的Spring AOP

4.1 @EnableAspectJAutoProxy的作用

@EnableAspectJAutoProxy注解是開(kāi)啟Spring AOP注解支持的關(guān)鍵:

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}

該注解的作用是向Spring容器注冊(cè)一個(gè)AnnotationAwareAspectJAutoProxyCreator Bean,這是一個(gè)BeanPostProcessor,負(fù)責(zé):

  • 解析@Aspect注解的類(lèi)
  • @Before、@After等注解轉(zhuǎn)換為對(duì)應(yīng)的Advisor
  • 在Bean初始化后創(chuàng)建代理對(duì)象

4.2 注解使用示例

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("Before method: " + joinPoint.getSignature().getName());
    }
    @AfterReturning(
        pointcut = "execution(* com.example.service.*.*(..))",
        returning = "result"
    )
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("Method returned: " + result);
    }
    @AfterThrowing(
        pointcut = "execution(* com.example.service.*.*(..))",
        throwing = "error"
    )
    public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {
        System.out.println("Method threw exception: " + error);
    }
    @After("execution(* com.example.service.*.*(..))")
    public void logAfter(JoinPoint joinPoint) {
        System.out.println("After method (finally)");
    }
    @Around("execution(* com.example.service.*.*(..))")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Around before");
        Object result = joinPoint.proceed();
        System.out.println("Around after");
        return result;
    }
}

五、代理對(duì)象的創(chuàng)建過(guò)程

5.1 JdkDynamicAopProxy創(chuàng)建過(guò)程

public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {
    public JdkDynamicAopProxy(AdvisedSupport config) {
        // 1. 獲取目標(biāo)類(lèi)實(shí)現(xiàn)的所有接口
        Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(config);
        // 2. 額外添加三個(gè)接口
        List<Class<?>> allInterfaces = new ArrayList<>(Arrays.asList(proxiedInterfaces));
        allInterfaces.add(SpringProxy.class);
        allInterfaces.add(Advised.class);
        allInterfaces.add(DecoratingProxy.class);
        // 3. 檢查接口中的equals和hashCode方法
        findDefinedEqualsAndHashCodeMethods(allInterfaces);
        // 4. 創(chuàng)建代理對(duì)象
        this.proxiedInterfaces = allInterfaces.toArray(new Class<?>[0]);
    }
    @Override
    public Object getProxy(@Nullable ClassLoader classLoader) {
        return Proxy.newProxyInstance(
            classLoader, 
            this.proxiedInterfaces, 
            this
        );
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 代理對(duì)象的執(zhí)行邏輯
        // ...
    }
}

5.2 ObjenesisCglibAopProxy創(chuàng)建過(guò)程

public class ObjenesisCglibAopProxy extends CglibAopProxy {
    @Override
    public Object getProxy(@Nullable ClassLoader classLoader) {
        // 1. 創(chuàng)建Enhancer對(duì)象
        Enhancer enhancer = createEnhancer();
        // 2. 設(shè)置父類(lèi)(目標(biāo)類(lèi))
        enhancer.setSuperclass(config.getTargetClass());
        // 3. 設(shè)置接口
        enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(config));
        // 4. 設(shè)置回調(diào)
        enhancer.setCallback(new DynamicAdvisedInterceptor(this.advised));
        // 5. 創(chuàng)建代理對(duì)象
        return enhancer.create();
    }
}

六、代理對(duì)象的執(zhí)行過(guò)程

6.1 代理方法執(zhí)行的核心流程

// 偽代碼展示代理對(duì)象方法執(zhí)行過(guò)程
public Object invoke(Method method, Object[] args) {
    // 1. 獲取所有Advisor
    List<Advisor> advisors = getAdvisors();
    // 2. 篩選與當(dāng)前方法匹配的Advisor
    List<Advisor> matchedAdvisors = filterAdvisors(advisors, method);
    // 3. 將Advisor轉(zhuǎn)換為MethodInterceptor
    List<MethodInterceptor> interceptors = 
        adaptAdvisorsToMethodInterceptors(matchedAdvisors);
    // 4. 創(chuàng)建MethodInvocation
    MethodInvocation invocation = new ReflectiveMethodInvocation(
        target, method, args, interceptors
    );
    // 5. 執(zhí)行攔截器鏈
    return invocation.proceed();
}

6.2 各注解對(duì)應(yīng)的MethodInterceptor執(zhí)行順序

注解對(duì)應(yīng)Interceptor執(zhí)行順序
@BeforeMethodBeforeAdviceInterceptor先執(zhí)行通知,后執(zhí)行目標(biāo)方法
@AfterReturningAfterReturningAdviceInterceptor先執(zhí)行目標(biāo)方法,后執(zhí)行通知
@AfterThrowingAspectJAfterThrowingAdvice先執(zhí)行目標(biāo)方法,異常時(shí)執(zhí)行通知
@AfterAspectJAfterAdvice先執(zhí)行目標(biāo)方法,后執(zhí)行通知(finally)
@AroundAspectJAroundAdvice完全控制執(zhí)行流程

執(zhí)行流程示意圖

   Around.before

              ↓

          Before

              ↓

     目標(biāo)方法執(zhí)行

              ↓

AfterReturning/AfterThrowing

              ↓

           After

              ↓

     Around.after

七、AbstractAdvisorAutoProxyCreator的工作原理

7.1 核心繼承體系

BeanPostProcessor
    ↓
AbstractAutoProxyCreator
    ↓
AbstractAdvisorAutoProxyCreator
    ↓
AspectJAwareAdvisorAutoProxyCreator
    ↓
AnnotationAwareAspectJAutoProxyCreator

7.2 關(guān)鍵方法解析

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
    @Override
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        // 1. 檢查是否已經(jīng)是代理對(duì)象
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            return bean;
        }
        // 2. 獲取所有Advisor
        List<Advisor> advisors = getAdvisors();
        // 3. 查找匹配的Advisor
        List<Advisor> matchedAdvisors = findAdvisorsThatCanApply(advisors, bean.getClass(), beanName);
        // 4. 如果有匹配的Advisor,創(chuàng)建代理對(duì)象
        if (!matchedAdvisors.isEmpty()) {
            return createProxy(bean.getClass(), beanName, matchedAdvisors, bean);
        }
        return bean;
    }
    protected List<Advisor> getAdvisors() {
        // 獲取所有Advisor類(lèi)型的Bean
        List<Advisor> advisors = new ArrayList<>();
        String[] advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
            this.beanFactory, Advisor.class, true, false
        );
        for (String name : advisorNames) {
            advisors.add(this.beanFactory.getBean(name, Advisor.class));
        }
        return advisors;
    }
}

7.3 AnnotationAwareAspectJAutoProxyCreator的特殊處理

AnnotationAwareAspectJAutoProxyCreator重寫(xiě)了getAdvisors()方法,增加了對(duì)@Aspect注解的解析:

public class AnnotationAwareAspectJAutoProxyCreator 
        extends AspectJAwareAdvisorAutoProxyCreator {
    @Override
    protected List<Advisor> getAdvisors() {
        // 調(diào)用父類(lèi)方法獲取已注冊(cè)的Advisor
        List<Advisor> advisors = super.getAdvisors();
        // 額外解析@Aspect注解的Bean
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        return advisors;
    }
}

八、Spring AOP高級(jí)特性

8.1 TargetSource:靈活的代理目標(biāo)源

TargetSource允許我們動(dòng)態(tài)控制被代理對(duì)象的獲取:

TargetSource ts = new TargetSource() {
    @Override
    public Class<?> getTargetClass() {
        return UserService.class;
    }
    @Override
    public boolean isStatic() {
        return false; // 每次調(diào)用都獲取新的目標(biāo)對(duì)象
    }
    @Override
    public Object getTarget() {
        // 動(dòng)態(tài)創(chuàng)建或獲取目標(biāo)對(duì)象
        return new UserService();
    }
    @Override
    public void releaseTarget(Object target) {
        // 釋放目標(biāo)對(duì)象
    }
};
ProxyFactory pf = new ProxyFactory();
pf.setTargetSource(ts);

應(yīng)用場(chǎng)景:延遲注入(@Lazy)、熱替換等

8.2 Introduction:引入新接口

Introduction允許為被代理對(duì)象動(dòng)態(tài)添加新的接口實(shí)現(xiàn):

@Aspect
@Component
public class IntroductionAspect {
    @DeclareParents(
        value = "com.example.service.*+",
        defaultImpl = DefaultLockable.class
    )
    public static Lockable mixin;
}
public interface Lockable {
    void lock();
    void unlock();
    boolean isLocked();
}
public class DefaultLockable 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;
    }
}

8.3 LoadTimeWeaving:加載時(shí)織入

Spring AOP支持在類(lèi)加載時(shí)進(jìn)行字節(jié)碼織入:

@Configuration
@EnableLoadTimeWeaving
public class AppConfig {
}
// 或使用XML配置
// <context:load-time-weaver/>

與運(yùn)行時(shí)織入的區(qū)別

  • 運(yùn)行時(shí)織入:通過(guò)動(dòng)態(tài)代理在運(yùn)行時(shí)增強(qiáng)
  • 加載時(shí)織入:在類(lèi)加載時(shí)修改字節(jié)碼,性能更高

九、Spring AOP與AspectJ的關(guān)系

9.1 兩者區(qū)別

特性Spring AOPAspectJ
實(shí)現(xiàn)方式動(dòng)態(tài)代理(運(yùn)行時(shí))字節(jié)碼操作(編譯時(shí)/加載時(shí))
性能相對(duì)較慢非???/td>
功能有限,僅支持方法級(jí)別強(qiáng)大,支持字段、構(gòu)造器等
依賴僅需Spring需要AspectJ編譯器/織入器
使用場(chǎng)景大多數(shù)企業(yè)應(yīng)用需要高級(jí)AOP功能的場(chǎng)景

9.2 Spring如何整合AspectJ

Spring并沒(méi)有使用AspectJ的編譯器或織入器,而是:

  • 復(fù)用注解:直接使用AspectJ定義的注解(@Aspect、@Before等)
  • 自行解析:Spring自己解析這些注解并轉(zhuǎn)換為內(nèi)部表示
  • 動(dòng)態(tài)代理實(shí)現(xiàn):通過(guò)動(dòng)態(tài)代理實(shí)現(xiàn)AOP功能

十、性能優(yōu)化與最佳實(shí)踐

10.1 性能優(yōu)化建議

合理選擇代理方式

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true) // 強(qiáng)制使用CGLIB
public class AppConfig {
}

精確指定切點(diǎn)

// 不推薦:過(guò)于寬泛
@Before("execution(* *.*(..))")
// 推薦:精確匹配
@Before("execution(* com.example.service.UserService.*(..))")

避免在Advice中做耗時(shí)操作

@Around("execution(* com.example.service.*.*(..))")
public Object measurePerformance(ProceedingJoinPoint joinPoint) throws Throwable {
    long start = System.currentTimeMillis();
    Object result = joinPoint.proceed();
    long end = System.currentTimeMillis();
    log.info("方法執(zhí)行時(shí)間: {}ms", end - start);
    return result;
}

10.2 常見(jiàn)問(wèn)題與解決方案

10.2.1 自調(diào)用問(wèn)題

@Service
public class UserService {
    public void methodA() {
        System.out.println("methodA");
        this.methodB(); // 自調(diào)用,不會(huì)觸發(fā)AOP
    }
    @Transactional
    public void methodB() {
        System.out.println("methodB");
    }
}
// 解決方案1:從容器中獲取代理對(duì)象
@Service
public class UserService {
    @Autowired
    private ApplicationContext context;
    public void methodA() {
        System.out.println("methodA");
        context.getBean(UserService.class).methodB();
    }
}
// 解決方案2:使用AspectJ
@Configuration
@EnableAspectJAutoProxy(exposeProxy = true)
public class AppConfig {
}
@Service
public class UserService {
    public void methodA() {
        System.out.println("methodA");
        ((UserService) AopContext.currentProxy()).methodB();
    }
}

10.2.2 循環(huán)依賴問(wèn)題

// 當(dāng)A和B相互依賴且都需要AOP時(shí)可能出現(xiàn)問(wèn)題
// 解決方案:使用setter注入而非構(gòu)造器注入
@Service
public class ServiceA {
    private ServiceB serviceB;
    @Autowired
    public void setServiceB(ServiceB serviceB) {
        this.serviceB = serviceB;
    }
}

十一、總結(jié)

Spring AOP是一個(gè)強(qiáng)大而靈活的AOP實(shí)現(xiàn)框架,其核心機(jī)制可以總結(jié)如下:

  • 動(dòng)態(tài)代理是基礎(chǔ):Spring AOP基于JDK動(dòng)態(tài)代理和CGLIB兩種技術(shù)實(shí)現(xiàn)
  • 統(tǒng)一抽象層:通過(guò)ProxyFactory、Advisor、Advice等概念提供統(tǒng)一API
  • 注解驅(qū)動(dòng):支持使用@Aspect、@Before等注解聲明式配置AOP
  • 自動(dòng)代理:通過(guò)BeanPostProcessor機(jī)制自動(dòng)創(chuàng)建代理對(duì)象
  • 執(zhí)行鏈:通過(guò)MethodInterceptor鏈實(shí)現(xiàn)多個(gè)通知的順序執(zhí)行

Spring AOP的設(shè)計(jì)體現(xiàn)了以下幾個(gè)重要原則:

  • 開(kāi)閉原則:通過(guò)代理模式實(shí)現(xiàn)對(duì)目標(biāo)對(duì)象的透明增強(qiáng)
  • 單一職責(zé):將橫切關(guān)注點(diǎn)(日志、事務(wù)等)與業(yè)務(wù)邏輯分離
  • 配置優(yōu)于編碼:支持XML、注解等多種配置方式

到此這篇關(guān)于Spring AOP底層源碼深度解析之從動(dòng)態(tài)代理到注解實(shí)現(xiàn)的完整架構(gòu)的文章就介紹到這了,更多相關(guān)Spring AOP動(dòng)態(tài)代理到注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mybatisplus實(shí)現(xiàn)自動(dòng)填充時(shí)間的項(xiàng)目實(shí)踐

    mybatisplus實(shí)現(xiàn)自動(dòng)填充時(shí)間的項(xiàng)目實(shí)踐

    在數(shù)據(jù)庫(kù)操作中,頻繁設(shè)置創(chuàng)建時(shí)間和更新時(shí)間字段非常繁瑣,通過(guò)使用MyBatis-Plus的自動(dòng)填充功能,可以簡(jiǎn)化操作,本文就來(lái)詳細(xì)的介紹一下,感興趣的可以了解一下
    2024-10-10
  • 實(shí)時(shí)計(jì)算知多少?

    實(shí)時(shí)計(jì)算知多少?

    這篇文章對(duì)滑動(dòng)窗口計(jì)數(shù)的概念和關(guān)鍵代碼做了較為詳細(xì)解釋?zhuān)屛覀儗?duì)實(shí)時(shí)計(jì)算這一概念有了更深的了解,需要的朋友可以參考下
    2015-07-07
  • MyBatis中動(dòng)態(tài)SQL的使用指南

    MyBatis中動(dòng)態(tài)SQL的使用指南

    MyBatis 是一個(gè)流行的持久層框架,它通過(guò) XML 或注解將接口方法與 SQL 映射在一起,動(dòng)態(tài) SQL 是 MyBatis 的一大特性,它使得構(gòu)建靈活的查詢變得簡(jiǎn)單,本文將通過(guò)一個(gè) User 表的示例,介紹 MyBatis 中常用的動(dòng)態(tài) SQL 方法,需要的朋友可以參考下
    2024-09-09
  • BaseDao封裝增刪改查的代碼詳解

    BaseDao封裝增刪改查的代碼詳解

    本篇文章主要介紹對(duì)數(shù)據(jù)庫(kù)中表中的數(shù)據(jù)進(jìn)行增改刪查詢,封裝一個(gè)工具類(lèi)(BaseDao)的詳細(xì)使用以及部分理論知識(shí),并通過(guò)代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-03-03
  • SpringBoot實(shí)現(xiàn)方法級(jí)別的環(huán)境隔離的幾種方式

    SpringBoot實(shí)現(xiàn)方法級(jí)別的環(huán)境隔離的幾種方式

    在 Spring Boot 中實(shí)現(xiàn)環(huán)境隔離和多環(huán)境配置管理是項(xiàng)目部署和維護(hù)中的關(guān)鍵部分,通過(guò)靈活的配置機(jī)制,開(kāi)發(fā)者可以輕松應(yīng)對(duì)開(kāi)發(fā)、測(cè)試和生產(chǎn)等不同環(huán)境的需求,以下是實(shí)現(xiàn)這些目標(biāo)的核心方法和最佳實(shí)踐,需要的朋友可以參考下
    2025-07-07
  • java算法題解??虰M99順時(shí)針旋轉(zhuǎn)矩陣示例

    java算法題解??虰M99順時(shí)針旋轉(zhuǎn)矩陣示例

    這篇文章主要為大家介紹了java算法題解牛客BM99順時(shí)針旋轉(zhuǎn)矩陣示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Spring動(dòng)態(tài)加載bean后調(diào)用實(shí)現(xiàn)方法解析

    Spring動(dòng)態(tài)加載bean后調(diào)用實(shí)現(xiàn)方法解析

    這篇文章主要介紹了Spring動(dòng)態(tài)加載bean后調(diào)用實(shí)現(xiàn)方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • spring boot+redis 監(jiān)聽(tīng)過(guò)期Key的操作方法

    spring boot+redis 監(jiān)聽(tīng)過(guò)期Key的操作方法

    這篇文章主要介紹了spring boot+redis 監(jiān)聽(tīng)過(guò)期Key,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • spring中REST和RESTful的區(qū)別以及基本實(shí)現(xiàn)

    spring中REST和RESTful的區(qū)別以及基本實(shí)現(xiàn)

    本文主要介紹了spring中REST和RESTful的區(qū)別以及基本實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • Java隱藏特性之雙括號(hào)初始化詳解

    Java隱藏特性之雙括號(hào)初始化詳解

    Java?語(yǔ)言擁有許多隱藏而強(qiáng)大的特性,其中之一是雙括號(hào)初始化,這篇文章將詳細(xì)介紹雙括號(hào)初始化的概念、用法和示例代碼,希望對(duì)大家有所幫助
    2023-12-12

最新評(píng)論

璧山县| 绿春县| 卓资县| 会宁县| 乐平市| 霞浦县| 额尔古纳市| 冕宁县| 永登县| 财经| 凤城市| 长治县| 石屏县| 云安县| 闸北区| 潼关县| 上栗县| 隆德县| 东乡族自治县| 沭阳县| 二连浩特市| 阳泉市| 资源县| 温泉县| 德兴市| 神木县| 弋阳县| 安岳县| 阳泉市| 潢川县| 左云县| 万安县| 垫江县| 平乡县| 逊克县| 巫山县| 贺兰县| 宁晋县| 盘山县| 肇州县| 宁波市|