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

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

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

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

1.1 代理模式的核心思想

代理模式的本質(zhì)是:為其他對象提供一種代理以控制對這個對象的訪問。在Spring AOP中,我們通過代理模式來增強目標對象的方法。

1.2 JDK動態(tài)代理與CGLIB對比

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

public class UserService {
    public void test() {
        System.out.println("test...");
    }
}
// CGLIB動態(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特點

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

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

public interface UserInterface {
    void test();
}
public class UserService implements UserInterface {
    public void test() {
        System.out.println("test...");
    }
}
// JDK動態(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動態(tài)代理特點

  • 基于接口實現(xiàn)
  • 只能代理實現(xiàn)了接口的類
  • 使用反射機制,性能相對較低

1.3 Spring的選擇策略

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

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

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

  • optimize為true → CGLIB
  • proxyTargetClass為true → CGLIB
  • 目標類沒有實現(xiàn)接口 → CGLIB
  • 目標類是接口或已經(jīng)是代理類 → JDK動態(tài)代理
  • 其他情況 → JDK動態(tài)代理

二、Spring AOP核心概念詳解

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

ProxyFactory是Spring提供的統(tǒng)一代理創(chuà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:通知的類型

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

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

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í)行目標方法
        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í)行后邏輯(一定會執(zhí)行)
        System.out.println("After method (finally)");
    }
}

2.3 Advisor:切面 = 切點 + 通知

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

UserService target = new UserService();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvisor(new PointcutAdvisor() {
    @Override
    public Pointcut getPointcut() {
        // 定義切點:只匹配名為"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;
    }
}

特點

  • 基于FactoryBean機制
  • 可以針對單個Bean進行AOP配置
  • 支持通過名稱引用已定義的Advice

3.2 BeanNameAutoProxyCreator:按Bean名稱匹配

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

特點

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

3.3 DefaultAdvisorAutoProxyCreator:自動代理創(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();
}

特點

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

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

4.1 @EnableAspectJAutoProxy的作用

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

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}

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

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

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;
    }
}

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

5.1 JdkDynamicAopProxy創(chuàng)建過程

public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {
    public JdkDynamicAopProxy(AdvisedSupport config) {
        // 1. 獲取目標類實現(xiàn)的所有接口
        Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(config);
        // 2. 額外添加三個接口
        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)建代理對象
        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 {
        // 代理對象的執(zhí)行邏輯
        // ...
    }
}

5.2 ObjenesisCglibAopProxy創(chuàng)建過程

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

六、代理對象的執(zhí)行過程

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

// 偽代碼展示代理對象方法執(zhí)行過程
public Object invoke(Method method, Object[] args) {
    // 1. 獲取所有Advisor
    List<Advisor> advisors = getAdvisors();
    // 2. 篩選與當前方法匹配的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 各注解對應(yīng)的MethodInterceptor執(zhí)行順序

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

執(zhí)行流程示意圖

   Around.before

              ↓

          Before

              ↓

     目標方法執(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)是代理對象
        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)建代理對象
        if (!matchedAdvisors.isEmpty()) {
            return createProxy(bean.getClass(), beanName, matchedAdvisors, bean);
        }
        return bean;
    }
    protected List<Advisor> getAdvisors() {
        // 獲取所有Advisor類型的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重寫了getAdvisors()方法,增加了對@Aspect注解的解析:

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

八、Spring AOP高級特性

8.1 TargetSource:靈活的代理目標源

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

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

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

8.2 Introduction:引入新接口

Introduction允許為被代理對象動態(tài)添加新的接口實現(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:加載時織入

Spring AOP支持在類加載時進行字節(jié)碼織入:

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

與運行時織入的區(qū)別

  • 運行時織入:通過動態(tài)代理在運行時增強
  • 加載時織入:在類加載時修改字節(jié)碼,性能更高

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

9.1 兩者區(qū)別

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

9.2 Spring如何整合AspectJ

Spring并沒有使用AspectJ的編譯器或織入器,而是:

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

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

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

合理選擇代理方式

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

精確指定切點

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

避免在Advice中做耗時操作

@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í)行時間: {}ms", end - start);
    return result;
}

10.2 常見問題與解決方案

10.2.1 自調(diào)用問題

@Service
public class UserService {
    public void methodA() {
        System.out.println("methodA");
        this.methodB(); // 自調(diào)用,不會觸發(fā)AOP
    }
    @Transactional
    public void methodB() {
        System.out.println("methodB");
    }
}
// 解決方案1:從容器中獲取代理對象
@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)依賴問題

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

十一、總結(jié)

Spring AOP是一個強大而靈活的AOP實現(xiàn)框架,其核心機制可以總結(jié)如下:

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

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

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

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

相關(guān)文章

  • mybatisplus實現(xiàn)自動填充時間的項目實踐

    mybatisplus實現(xiàn)自動填充時間的項目實踐

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

    實時計算知多少?

    這篇文章對滑動窗口計數(shù)的概念和關(guān)鍵代碼做了較為詳細解釋,讓我們對實時計算這一概念有了更深的了解,需要的朋友可以參考下
    2015-07-07
  • MyBatis中動態(tài)SQL的使用指南

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

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

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

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

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

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

    java算法題解牛客BM99順時針旋轉(zhuǎn)矩陣示例

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

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

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

    spring boot+redis 監(jiān)聽過期Key的操作方法

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

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

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

    Java隱藏特性之雙括號初始化詳解

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

最新評論

济源市| 平泉县| 札达县| 临泉县| 临高县| 五华县| 库车县| 永善县| 彭水| 东辽县| 锡林郭勒盟| 汤原县| 双鸭山市| 神池县| 尉犁县| 龙陵县| 墨江| 墨玉县| 阆中市| 宝丰县| 浮山县| 水城县| 平阴县| 东光县| 闻喜县| 勐海县| 临西县| 邹平县| 正宁县| 汨罗市| 綦江县| 涿鹿县| 邻水| 梓潼县| 博爱县| 龙岩市| 海南省| 邢台市| 什邡市| 安图县| 楚雄市|