Gaining Access to the Spring Context in Non Spring Managed Classes

本文介绍了一种无需将整个应用整合到Spring框架中即可使用Spring Bean的方法。通过创建一个实现了ApplicationContextAware接口的静态类SpringContext,并将其配置在application-context.xml文件中,可以在任何需要的地方轻松获取Spring Bean实例。

There are times where it’s not practical (or possible) to wire up your entire application into the Spring framework, but you still need a Spring loaded bean in order to perform a task.  JSP tags and legacy code are two such examples.   Here is a quick and easy way to get access to the application context.

First we create a class that has a dependency on the spring context.  The magic here is a combination of implementing ApplicationContextAware and defining the ApplicatonContext object as static.

package com.objectpartners.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class SpringContext implements ApplicationContextAware {
  private static ApplicationContext context;

  public void setApplicationContext(ApplicationContext context) throws BeansException {
    this.context = context;
  }
  public static ApplicationContext getApplicationContext() {
    return context;
  }
}

Next,  we wire SpringContext into our spring container by defining it in our application-context.xml:

<bean id="springContext" class="com.objectpartners.util.SpringContext />

Now,  anywhere we need access to the spring context we can import SpringContext and call the getApplicationContext method like so:

import com.objectpartners.util.SpringContext;
class LegacyCode {
.
.

  SpringBean bean = (SpringBean)SpringContext.getApplicationContext.getBean("springBean");
.
.
}

Keep in mind that if there are multiple spring containers running on the JVM the static ApplicationContext object will be overwritten by the last container loaded so this approach may not work for you.

Living in a **post–Spring Cloud Netflix** world means embracing the evolution of microservices architecture beyond the once-dominant stack of **Eureka, Ribbon, Hystrix, and Zuul**, which have all entered maintenance mode or been deprecated by Netflix and later removed from Spring Cloud. The good news? The ecosystem has matured. You're not losing functionality — you're gaining **more flexibility, cloud-native alignment, and better integration with modern platforms like Kubernetes**. Here’s how to thrive in this new era: --- ### 🔚 Why Did Spring Cloud Netflix End? | Component | Status | Reason | |---------|--------|--------| | **Eureka** | In maintenance (Netflix) | Self-preservation mode; no new features | | **Ribbon** | Deprecated | Client-side load balancing replaced by Spring Cloud LoadBalancer | | **Hystrix** | Deprecated | Circuit breaking evolved into Resilience4j and resilience patterns | | **Zuul 1/2** | Abandoned | Outdated model; replaced by Spring Cloud Gateway | > ⚠️ As of **Spring Cloud 2020.0.0 (Ilford)**, these components are **no longer included** in the default release train. --- ## ✅ How to Adapt: Key Replacements & Strategies ### 1. ❌ Replace Eureka with Service Discovery Alternatives #### 🔄 Option A: Use **Spring Cloud Kubernetes** - Automatically discovers services via Kubernetes DNS and APIs. - No need for a separate registry. ```yaml # application.yml spring: cloud: kubernetes: discovery: all-namespaces: false ``` ✅ Pros: Native to K8s, zero additional infrastructure ❌ Cons: Tied to Kubernetes only #### 🔄 Option B: Use **Hashicorp Consul** - Full-service mesh capabilities. - Health checks, KV store, UI. ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> ``` ✅ Pros: Multi-platform, rich feature set ❌ Cons: Requires running Consul agents/servers #### 🔄 Option C: Use **Nacos (by Alibaba)** - Dynamic service discovery, config management, and service metadata. - Popular in China and growing globally. ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> ``` ✅ Pros: All-in-one solution (config + discovery) ❌ Cons: Less familiar outside Alibaba ecosystem --- ### 2. ❌ Replace Ribbon with Spring Cloud LoadBalancer Now the **default client-side load balancer**. #### Usage Example: ```java @RestController public class MyController { @LoadBalanced @Bean WebClient.Builder webClientBuilder() { return WebClient.builder(); } @Autowired WebClient.Builder webClientBuilder; @GetMapping("/call-service") public Mono<String> callService() { return webClientBuilder.build() .get().uri("http://my-microservice/api/data") .retrieve() .bodyToMono(String.class); } } ``` No configuration needed if using `spring-cloud-starter-loadbalancer`. ✅ Supports reactive (`WebClient`) and imperative (`RestTemplate`) styles ✅ Pluggable: Can integrate with service mesh or custom providers --- ### 3. ❌ Replace Hystrix with Resilience4j Modern, functional, lightweight circuit breaker and fault tolerance library. #### Add Dependency: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId> </dependency> ``` #### Configure Circuit Breaker: ```yaml resilience4j: circuitbreaker: instances: backendA: failureRateThreshold: 50 waitDurationInOpenState: 5000ms ringBufferSizeInHalfOpenState: 3 ``` #### Use It: ```java @CircuitBreaker(name = "backendA", fallbackMethod = "fallback") public String getData() { return webClient.get().uri("/api/data").retrieve().bodyToMono(String.class).block(); } public String fallback(Exception e) { return "Fallback response"; } ``` ✅ Lightweight, thread-isolated or semaphore-based ✅ Integrates well with Micrometer, Retry, Rate Limiter, Bulkhead --- ### 4. ❌ Replace Zuul with Spring Cloud Gateway The **official successor**: built on **Spring WebFlux (Reactor)**, fully non-blocking, high-performance API gateway. #### Features: - Route matching (path, host, headers) - Filters (pre/post) - Rate limiting - WebSocket support - Integration with OAuth2, Security, etc. #### Example Route Configuration: ```yaml spring: cloud: gateway: routes: - id: user-service uri: lb://user-service predicates: - Path=/users/** filters: - RewritePath=/users/(?<path>.*), /$\{path} ``` > `lb://` means use load balancing via Spring Cloud LoadBalancer. ✅ High throughput, low latency ✅ Reactive stack enables scalability ✅ Rich filter ecosystem --- ### 5. Embrace Platform-Native Patterns (Especially on Kubernetes) Instead of building your own resilience layer, consider leveraging: | Tool | Purpose | |------|--------| | **Istio / Linkerd** | Service mesh for mTLS, retries, timeouts, observability | | **Kubernetes Services & Ingress** | Built-in routing, health checks, rolling updates | | **Argo Rollouts / Flagger** | Progressive delivery (canary, blue/green) | | **Prometheus + Grafana + OpenTelemetry** | Observability without Hystrix Dashboard | > 💡 Think: *"Do I really need client-side logic?"* Often, the answer is **no** — let the platform handle it. --- ## 🧭 Mindset Shift: From Library-Centric to Platform-Centric | Old World (Netflix Stack) | New World (Cloud-Native) | |---------------------------|----------------------------| | Run everything inside JVM | Leverage sidecars and operators | | Build resilience in code | Defer to service mesh | | Manage discovery manually | Use K8s DNS/service abstraction | | Monolithic gateways | Edge + service mesh split | | Centralized tooling | GitOps, declarative configs | 👉 Focus shifts from **"what libraries do I add?"** to **"how is my platform configured?"** --- ## 🛠️ Migration Checklist | Step | Action | |------|--------| | 1 | Remove `spring-cloud-starter-netflix-*` dependencies | | 2 | Add `spring-cloud-starter-loadbalancer` | | 3 | Replace `RestTemplate` with `WebClient` (or keep but annotate with `@LoadBalanced`) | | 4 | Switch to `Resilience4j` or rely on service mesh for circuit breaking | | 5 | Replace Zuul with **Spring Cloud Gateway** | | 6 | Choose a discovery mechanism: K8s, Consul, Nacos | | 7 | Adopt externalized config: Config Server → **ConfigMap + Secret / Vault / Nacos** | | 8 | Implement observability: Micrometer + Prometheus + Tracing (Zipkin/Jaeger) | --- ## ✅ Summary: Thriving Post–Spring Cloud Netflix You don’t need Netflix OSS to build resilient, scalable microservices. Instead: > **Use Spring Cloud + Kubernetes + Modern Primitives = Better Outcome** 🔧 Tools you should now embrace: - ✅ **Spring Cloud Gateway** - ✅ **Spring Cloud LoadBalancer** - ✅ **Resilience4j** - ✅ **Spring Cloud Kubernetes / Consul / Nacos** - ✅ **Service Mesh (optional but powerful)** 🎯 Design principles: - Prefer **infrastructure-level resilience** over library-level where possible - Favor **GitOps, declarative config, and automation** - Build **polyglot systems** that aren't tied to Java-only solutions ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值