关于Spring/SpringBoot在静态工具类中注入Service的解决方案

一.springboot不会扫表到工具类,因为工具类的方法都是静态方法,是属于类的,所以没法加载到容器中。

但是由于Spring/SpringBoot正常情况下不能支持注入静态属性(会报空指针异常)。主要原因在于:Spring的依赖注入实际上是依赖于Set方法进行注入值的,Spring是基于对象层面的依赖注入,而静态属性/静态变量实际上是属于类的。

二.使用工具类发送邮件

核心:
解决方案:

  1. 给当前的工具类加上@Component,使其成为一个bean对象

  2. 声明一个静态的属性(加上注解@Autowired),一个非静态的属性。

  3. 声明一个返回值为void并且不能抛出异常的方法,在其中将非静态属性赋值给静态属性。

  4. 该方法上加上注解@PostConstruct

  5. 这样就将service的值注入了进来。示例代码如下:

    @Autowired
    JavaMailSenderImpl mailSender;//邮箱
    @Autowired
    static JavaMailSenderImpl JmailSender;//邮箱
    @PostConstruct
    public void init() {
    JmailSender = mailSender;
    }

package com.wcy.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@Component
public class EmilUtil {
    @Autowired
    JavaMailSenderImpl mailSender;//邮箱
    @Autowired
    static JavaMailSenderImpl JmailSender;//邮箱

    @PostConstruct
    public void init() {
        JmailSender = mailSender;
    }
    // 随机验证码
    public  String achieveCode() {
        String[] beforeShuffle= new String[] { "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F",
                "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a",
                "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
                "w", "x", "y", "z" };
        List list = Arrays.asList(beforeShuffle);
        Collections.shuffle(list);//置换顺序
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            sb.append(list.get(i));
        }
        String afterShuffle = sb.toString();
        String result = afterShuffle.substring(3, 9);//随机拆解数据
        System.out.print(result);
        return result;
    }

    /**
     * 发送邮箱工具类
     * @param from 发送邮箱
     * @param to 接收邮箱
     * @param title 主题(标题
     * @param conetnt 内容
     */
    public  static Boolean sendEmil(String from,String to,String title,String conetnt){
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);//发件人
        message.setTo(to);//收件人
        message.setSubject(title);
        message.setText(conetnt);//包含验证码
        try {
            //JavaMailSenderImpl mailSender=new JavaMailSenderImpl();//邮箱
            JmailSender.send(message);
            System.out.println("发送成功");
            return true;
            //logger.info("简单邮件已经发送。");
        } catch (Exception e) {
            System.out.println("发送简单邮件时发生异常!"+e);
        }
        return false;
    }
}

三.springboot使用这两个注解能解决使用静态工具类的方法

在上述代码中@PostConstruct是Java EE5规范之后,Servlet新增的两个影响servlet声明周期的注解之一,另外一个是@PreConstruct。这两个都可以用来修饰一个非静态的返回值为void的方法,并且该方法不能抛出异常。

  1. 被@PostConstruct注解修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet中的init方法。被该注解修饰的方法会在构造器执行之后,init方法执行之前执行。Spring中允许开发者在受理的Bean中去使用它,当IOC容器被实例化管理当前bean时,被该注解修饰的方法会执行,完成一些初始化的工作。
  2. 被PreConstruct注解修饰的方法会在服务器卸载Servlet的时候运行,类似于Servlet中的destroy方法。被该注解修饰的方法会在destroy方法执行之后,Servlet彻底卸载之前执行。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot 静态方法是没有办法直接获取到应用上下文的 Bean 的。如果你想要在静态方法使用其他 Service,有两种方法可以解决: 1. 使用依赖注入的方式: 在你的 Util 类定义一个 Service 属性,然后在 Util 类的构造函数Service 实例注入进来。这样就可以在 Util 类的非静态方法使用 Service 了。 2. 使用 Spring 的 ApplicationContextAware 接口: ApplicationContextAware 接口是 Spring 提供的一个接口,它允许某个 Bean 获取应用上下文的 ApplicationContext。你可以在你的 Util 类实现这个接口,然后在实现的 setApplicationContext() 方法将应用上下文保存下来。这样就可以在静态方法使用应用上下文获取其他 Bean 了。 例如: ``` import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public class Util implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) { Util.applicationContext = applicationContext; } public static Service getService() { return applicationContext.getBean(Service.class); } } ``` 这样,你就可以在 Util 类的静态方法使用 getService() 方法获取 Service 实例了。 ### 回答2: 在Spring Boot,可以通过@Autowired注解来注入其他Service,然后在Util工具类静态方法使用@Autowired注解进行注入。 首先,在Util工具类定义一个静态成员变量来存储注入Service对象。例如: ```java @Component public class ServiceUtil { private static OtherService otherService; @Autowired public void setOtherService(OtherService otherService) { ServiceUtil.otherService = otherService; } // 在静态方法使用otherService对象 public static void someMethod() { otherService.doSomething(); } } ``` 其,@Component注解用于将ServiceUtil类作为一个Spring管理的组件,使其成为可被@Autowired注入的对象。然后通过@Autowired注解来注入OtherService对象,并将其赋值给静态成员变量otherService。 在其他地方使用Util工具类静态方法时,可以直接调用someMethod()方法来访问其他Service。例如: ```java @Service public class MyService { public void myMethod() { ServiceUtil.someMethod(); } } ``` 上述代码,MyService类通过调用ServiceUtil类的静态方法someMethod()来访问OtherService对象,实现了在Util工具类静态方法拿到其他Service的目的。 ### 回答3: 在Spring Boot的Util工具类静态方法,我们不能直接通过注解的方式来注入其他Service,因为静态方法不属于任何实例化对象。但是我们可以通过ApplicationContext来获取其他Service对象。 首先,我们需要在启动类或者配置类注入ApplicationContext对象并将其声明为静态变量,以便在全局范围内访问。在注入时,可以使用Spring Boot提供的@Bean注解来将其交给Spring容器管理。 ```java @Configuration public class AppConfig { @Bean public static ApplicationContext applicationContext() { return new SpringApplicationBuilder(AppConfig.class).web(WebApplicationType.NONE).run(); } } ``` 然后,在Util工具类静态方法,可以通过ApplicationContext的静态方法getBean(Class<T> clazz)来获取其他Service的实例对象。 ```java public class MyUtil { private static ApplicationContext applicationContext; public static void setApplicationContext(ApplicationContext context) { applicationContext = context; } public static OtherService getOtherService() { return applicationContext.getBean(OtherService.class); } public static void doSomething() { OtherService otherService = getOtherService(); //... } } ``` 在其他的Service,只需要调用MyUtil.setApplicationContext(applicationContext)方法将ApplicationContext对象传入,即可在Util工具类静态方法获取到需要的Service。 需要注意的是,由于ApplicationContext是在Spring容器启动时初始化的,因此需要在获取其他Service之前先保证容器已经初始化完成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值