开门见山,直奔主题

亲测,两种方法,都好用,不说废话,直接看测试代码

一、使用工具类实现ApplicationContextAware获取ApplicationContenxt,再用ApplicationContenxt获取Spring容器中的bean
package com.ats.utils;

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

/**
 * 用来解决单例注入service为null,不用@Autowired,用ApplicationContext获取bean
 * @author zhaozhengge
 * @create 2021-04-30 16:00
 */
@Component
public class SpringContextUtils implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtils.applicationContext = applicationContext;
    }

    // 获取 ApplicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //通过name获取 Bean
    public static Object getBean(String name) {
        return applicationContext.getBean(name);
    }

    //通过class获取Bean
    public static <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }

    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name, Class<T> clazz) {
        return applicationContext.getBean(name, clazz);
    }
}

package com.ats.springboot.applicationRunner;

import com.ats.springboot.entity.Student;
import com.ats.springboot.service.StudentService;
import com.ats.springboot.utils.SpringContextUtils;
import com.ats.springboot.utils.TestUtil;
import com.ats.springboot.utils.TestUtil1;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author zhaozhengge
 * @create 2021-04-29 17:00
 */
@Component
@Slf4j
@Order(1)
public class MyApplicationRunner implements ApplicationRunner {

    private StudentService studentService;

    @Override
    public void run(ApplicationArguments args) {
        TestUtil1 testUtil1 = new TestUtil1();
        testUtil1.queryStudent();
    }
}
package com.ats.springboot.utils;

import com.ats.springboot.entity.Student;
import com.ats.springboot.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * @author zhaozhengge
 * @create 2021-04-30 21:06
 */
public class TestUtil1 {

    private StudentService studentService;

    public void queryStudent(){
        //通过工具类获取bean
        studentService = SpringContextUtils.getBean(StudentService.class);
        List<Student> list = studentService.list();
        System.out.println(list.toString());
    }
}

二、使用@PostConstruct注解和init()方法
package com.ats.springboot.utils;

import com.ats.springboot.entity.Student;
import com.ats.springboot.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * @author zhaozhengge
 * @create 2021-04-30 21:06
 */
@Component
public class TestUtil {

    @Autowired
    private StudentService studentService;
    private static TestUtil testUtil;

	/**
     * Java中该注解的说明:@PostConstruct该注解被用来修饰一个非静态的void()方法。
     * 被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。
     * PostConstruct在构造函数之后执行,init()方法之前执行。
     * 
     * 通常我们会是在Spring框架中使用到@PostConstruct注解 该注解的方法在整个Bean初始化中的执行顺序:
     * Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
     */
    @PostConstruct
    public void init(){
        testUtil = this;
    }

    public void queryStudent(){
        List<Student> list = testUtil.studentService.list();
        System.out.println(list.toString());
    }
}

package com.ats.springboot.applicationRunner;

import com.ats.springboot.utils.TestUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author zhaozhengge
 * @create 2021-04-29 17:00
 */
@Component
@Slf4j
@Order(1)
public class MyApplicationRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) {
        TestUtil testUtil = new TestUtil();
        testUtil.queryStudent();
    }
}

注意:该方法不适用于需要在构造函数中调用service
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐