@PostConstruct 静态方法中引用service层非静态方法

本文探讨了如何在静态方法中通过@PostConstruct注解正确注入非静态依赖,以避免LogUtil类静态引用CellMessageService时的空指针问题。作者展示了如何在LogUtils类中使用@Autowired和@PostConstruct进行初始化,确保在发送异常短信时能成功调用服务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里实例是,如果系统出现异常,就需要在LogUtil类中发送短信。就需要引用到CellMessageService。但LogUtil类中的方法都是静态方法。

@Autowired
private static CellMessageService messageService;
如果直接这样静态引用属性,那么这个属性不管怎么调用都是null。
这里就会涉及到静态类型的使用:
  1.静态属性会随着类加载而加载 
  2.静态方法里不能直接访问非静态成员变量。

所以遇到这种情况就可以用到@PostConstruct注解
 

@PostConstruct注解是Java自己的注解,不是Spring提供的。

应用:在静态方法中调用依赖注入的Bean中的方法。

@PostConstruct该注解被用来修饰一个非静态的void()方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。

通常我们会是在Spring框架中使用到@PostConstruct注解 该注解的方法在整个Bean初始化中的执行顺序:

Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)

public class LogUtils {

	private static CellMessageService messageService = new CellMessageService();
    //private static CellMessageService messageService;

	@Autowired
	private CellMessageService cellMessageService;
	@PostConstruct
	public void init(){
		messageService = cellMessageService;
	}
    public static void sendMessage(Exception ex){
        if(null!=ex){				
            try {
                //出现异常发送短信通知
                messageService.send("131****8308",null,"XXX系统出现异常!","太阳王",null);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

然后测试debug的时候就能成功实现了

### @PostConstruct 注解启动时未执行或未打印日志的原因及解决方案 在 Spring 应用中,`@PostConstruct` 注解用于标记一个方法,在 Bean 初始化完成后立即执行。如果该注解的方法未执行或未打印日志,可能由以下原因导致: #### 1. Bean 未被正确加载到 Spring 容器中 只有被 Spring 容器管理的 Bean 才会触发 `@PostConstruct` 方法的执行。如果类未标注为 `@Component` 或其变体(如 `@Service`、`@Repository`),则该类不会被 Spring 容器扫描和加载[^2]。 **解决方案**: 确保类被正确标注为 Spring 管理的 Bean,并位于组件扫描路径下。例如: ```java @Component public class MyBean { @PostConstruct public void init() { System.out.println("MyBean initialized!"); } } ``` #### 2. 静态方法实例化类 `@PostConstruct` 注解的方法必须是静态方法,且所在类需要被实例化。如果方法被声明为 `static` 或类未被实例化,则该方法不会被执行[^5]。 **解决方案**: 移除 `static` 修饰符,并确保类被正确实例化。例如: ```java @Component public class MyBean { @PostConstruct public void init() { // 不应为 static System.out.println("MyBean initialized!"); } } ``` #### 3. 日志框架未正确配置 即使 `@PostConstruct` 方法被执行,但如果日志框架未正确配置,也可能导致日志未打印。Spring Boot 默认使用 Logback 作为日志框架,开发者需要确保正确引入依赖并配置日志输出[^1]。 **解决方案**: 检查 `application.properties` 或 `application.yml` 文件,确保日志级别设置为 `INFO` 或更低。例如: ```properties logging.level.root=INFO ``` 同时,推荐使用日志框架替代 `System.out.println`,以实现更灵活的日志管理。例如: ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Component public class MyBean { private static final Logger logger = LoggerFactory.getLogger(MyBean.class); @PostConstruct public void init() { logger.info("MyBean initialized!"); } } ``` #### 4. 方法签名不符合要求 `@PostConstruct` 注解的方法必须满足以下条件:无参数、返回值为 `void`、不抛出已检查异常。如果方法签名不符合这些要求,则会导致注解失效。 **解决方案**: 调整方法签名以符合要求。例如: ```java @Component public class MyBean { @PostConstruct public void init() throws RuntimeException { // 可抛出运行时异常 System.out.println("MyBean initialized!"); } } ``` #### 5. 容器启动失败或 Bean 初始化顺序问题 如果容器启动失败,或者某些 Bean 的初始化顺序导致依赖注入问题,则可能导致 `@PostConstruct` 方法未执行。 **解决方案**: 检查容器启动日志,确保没有异常抛出。如果存在依赖注入问题,可以调整 Bean 的初始化顺序,或使用 `@DependsOn` 注解显式指定依赖关系。例如: ```java @Component @DependsOn("anotherBean") public class MyBean { @PostConstruct public void init() { System.out.println("MyBean initialized!"); } } ``` --- ### 示例代码 以下是一个完整的示例,展示如何正确使用 `@PostConstruct` 并打印日志: ```java import javax.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Component public class MyBean { private static final Logger logger = LoggerFactory.getLogger(MyBean.class); @PostConstruct public void init() { logger.info("MyBean initialized successfully!"); // 使用日志框架替代 System.out } } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值