spring项目获取ServletContext

最近项目在部署时总是报spring bean初始化空指针异常,只能把spring bean的包扫描配置放置在springMVC的配置文件中,项目才能正常启动,研究后发现是因为在spring的配置文件中获取servletContext的方法不对导致的

通常在spring项目中获取servletContext有以下方式
1、request获取servletContext

ServletContext servletContext = request.getServletContext();

2、使用ContextLoader

ServletContext servletContext = ContextLoader.getCurrentWebApplicationContext().getServletContext();

3、使用spring注入自动注入

@Autowired
private ServletContext servletContext;

之前的项目中代码使用@PostConstruct,在spring容器初始化时读取servletContext中内容,初始化bean,但使用的是第二种方式获取servletContext,但此时webApplicationContext还没有完成初始化,因此获取的是空值导致空指针异常,改成第三种方式获取servletContext就不会有这个问题

此时需要注意的是如果需要在spring容器初始化时读取servletContext中的值,那么servletContext值的初始化的servletContextListener一定要在org.springframework.web.context.ContextLoaderListener之前加载

### 如何在 Spring获取应用程序运行时的端口号 在 Spring 应用程序中,可以通过多种方式动态获取正在使用的端口号。以下是几种常见的方法: #### 方法一:通过 `LocalServerPort` 注解读取端口 如果需要在一个测试环境中或者控制器中读取端口号,可以使用 `@LocalServerPort` 注解。此注解会自动注入当前应用运行的实际端口号。 ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class PortTest { @LocalServerPort private int port; public void testPort() { System.out.println("Application is running on port: " + port); } } ``` 这种方法适用于单元测试场景或集成测试环境中的端口访问[^1]。 --- #### 方法二:通过 `EmbeddedWebServerFactoryCustomizer` 或 `ApplicationContext` 对于生产环境下的端口获取需求,可以在应用启动完成后通过监听事件的方式捕获实际分配的端口。 ```java import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class AppStartupRunner implements CommandLineRunner { @Value("${local.server.port}") private String serverPort; @Override public void run(String... args) throws Exception { System.out.println("The application has started and the current port is: " + serverPort); } } ``` 上述代码片段展示了如何利用 `${local.server.port}` 动态变量来获取嵌入式 Tomcat 实际分配的端口号[^3]。 --- #### 方法三:通过 `ServletWebServerApplicationContext` 获取端口 另一种更通用的方法是直接从 `ServletContext` 提供的信息中提取端口号。这种方式尤其适合于自定义逻辑实现的需求。 ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Component; import javax.servlet.ServletContext; import java.net.InetSocketAddress; @Component public class PortFinder implements ApplicationListener<ContextRefreshedEvent> { @Autowired ServletContext servletContext; @Override public void onApplicationEvent(ContextRefreshedEvent event) { InetSocketAddress address = (InetSocketAddress) servletContext.getAttribute("server.address"); if (address != null && address.getPort() > 0) { System.out.println("Current app port: " + address.getPort()); } else { System.out.println("Unable to determine the exact port."); } } } ``` 这段代码实现了基于上下文刷新事件的应用级监听器,在容器初始化完毕后打印出具体的端口号信息[^4]。 --- #### 方法四:通过命令行参数传递并解析 当设置了一个固定的端口号而非随机端口时,也可以通过外部配置文件(如 `application.properties` 或者 `-D` 参数)传入端口号,并手动加载这些值用于后续处理。 ```properties # application.properties server.port=8090 ``` 随后可通过如下方式进行读取: ```java import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @Service public class ConfigService { @Value("${server.port}") private Integer configuredPort; public Integer getPort() { return this.configuredPort; } } ``` 以上示例说明了静态配置下如何绑定服务端口到 Java Bean 属性上[^2]。 --- ### 总结 综上所述,有四种主要途径可用于不同场合下取得 Spring Boot 运行实例对应的 HTTP 监听端口。每种方案各有优劣,具体选用取决于项目的架构设计以及业务需求特点。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值