美文网首页
非 Spring 管理的 Bean 使用 SpringBean

非 Spring 管理的 Bean 使用 SpringBean

作者: 扮鬼之梦 | 来源:发表于2021-01-27 09:51 被阅读0次

    添加Spring工具类

    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;
    
    import java.util.Map;
    
    @Component
    public class SpringUtil implements ApplicationContextAware {
    
        private static ApplicationContext applicationContext;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            if (SpringUtil.applicationContext == null) {
                SpringUtil.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);
        }
    
        //通过Class返回指定的BeanMap
        public static <T> Map<String, T> getBeansOfType(Class<T> clazz) {
            return applicationContext.getBeansOfType(clazz);
        }
    
    }
    

    以 RestUtil工具类 使用 RestTemplate(Spring管理的Bean) 为例

    1. Spring注入RestTemplate

    import org.springframework.context.annotation.Bean;
    import org.springframework.stereotype.Component;
    import org.springframework.web.client.RestTemplate;
    
    @Component
    public class RestConfig {
        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }
    

    2. 创建Rest工具类

    import org.springframework.web.client.RestTemplate;
    
    public class RestUtil {
    
        private static RestTemplate restTemplate;
    
        static {
        // 使用SpringUtil 设置 RestUtil 的静态属性 restTemplate
            restTemplate = SpringUtil.getBean(RestTemplate.class);
        }
    
        private RestUtil() {
        }
    
        public static <T> T get(String url, Class<T> responseType) {
            return restTemplate.getForObject(url, responseType);
        }
    }
    

    3. 测试

    单元测试代码

    @Test
    public void restTest(){
        String url = "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?cardBinCheck=true&cardNo={{银行卡号}}";
        Map map = RestUtil.get(url, Map.class);
        System.out.println(JSON.toJSONString(map));
    }
    

    单元测试结果


    image

    4. 为什么在静态代码块中设置restTemplate?

    SpringBoot 启动完成时,RestUtil 没有实例化,RestUtil 的静态方法也未被调用过。所以在调用静态方法或实例化时,一定可以通过 SpringUtil 获取到 Spring Bean。然后 RestUtil 中的 restTemplate 只需要初始化一次,而静态代码块的代码只会执行一次,正好满足需求。

    关于类的代码块、静态代码块、构造器的加载时机测试代码

    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest
    class RestTest {
    
        // 实例化测试
        @Test
        void test1() {
            System.out.println("-------------------");
            new A();
            System.out.println("-------------------");
            new A();
            System.out.println("-------------------");
        }
    
        // 静态方法调用测试
        @Test
        void test2() {
            System.out.println("-------------------");
            A.a();
            System.out.println("-------------------");
            A.a();
            System.out.println("-------------------");
        }
    
    }
    
    class B {
        {
            System.out.println("父类非静态代码块");
        }
    
        static {
            System.out.println("父类静态代码块");
        }
    
        public B() {
            System.out.println("父类构造器");
        }
    }
    
    class A extends B {
        {
            System.out.println("子类非静态代码块");
        }
    
        static {
            System.out.println("子类静态代码块");
        }
    
        public A() {
            System.out.println("子类构造器");
        }
    
        public static void a() {
            System.out.println("执行方法a");
        }
    }
    

    test1结果


    test2结果


    相关文章

      网友评论

          本文标题:非 Spring 管理的 Bean 使用 SpringBean

          本文链接:https://www.haomeiwen.com/subject/imvozktx.html