zoukankan      html  css  js  c++  java
  • 不用注入方式使用Spring管理的对象中的方法,神奇

    在小冷工作中遇到这么一个小问题,当你的业务层对象交给spring管理之后,在普通的类中调用这个类中的方法时候,会有个问题这个类在调用时候会一直返回一个null,而且还会抛出一个空指针异常。

    小冷在遇到这个问题时候使用了各种方法发现很多都不能用,其中小冷罗列下生效的方法,并且网上还推荐使用的

    1.在普通类种也将自己注入交给spring管理

    首先看上面的,第一张图片,那个普通类似交给了spring管理的,并在这个类中注入了使用的业务层类,这个时候调用这个类中的方法时候,发现这个业务类返回是一个null,至于原因小冷下面解释。

    还有一种

    2.小冷使用实例化这个业务类,一般实例化的类会加入堆内存的这样试一下发现也不行

    3.使用类加载的方式将加载器在项目启动时就调用这个加载器,然后通过加载后的spring类加载器调用加载,这种是可以的

    综上所述只有第三种方法可以,这个里附上加载spring容器的中的实例化类的工具类

    package com.util;
    /*
     * @desc:提供非SPRING管理类调用管理类的功能
     * 注意在服务启动的时候进行import,apllication中引入
     */
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;
    ​
    ​
    @Component
    public class SpringUtil implements ApplicationContextAware {
           private static ApplicationContext applicationContext = null;
    ​
           @Override
    ​
           public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    ​
                  if (SpringUtil.applicationContext == null) {
                         SpringUtil.applicationContext = applicationContext;
                  }
                  System.out.println("---------------------------------------------------------------------");
                  System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext=" + SpringUtil.applicationContext + "========");
                  System.out.println("---------------------------------------------------------------------");
           }
    ​
           //获取applicationContext
           public static ApplicationContext getApplicationContext() {
                  return applicationContext;
           }
    ​
           //通过name获取 Bean.
           public static Object getBean(String name) {
                  return getApplicationContext().getBean(name);
           }
    ​
           //通过class获取Bean.
           public static <T> T getBean(Class<T> clazz) {
                  return getApplicationContext().getBean(clazz);
           }
    ​
           //通过name,以及Clazz返回指定的Bean
           public static <T> T getBean(String name, Class<T> clazz) {
                  return getApplicationContext().getBean(name, clazz);
           }
    }

    使用方式工具类中有注释;就不一一赘述

    这里小冷按自己理解说一下为啥前两种方式无法使用,如有不同理解和更为准确的解释欢迎私信留言!!!!关注我公众号“秦川以北”

    先说一下第一种:小冷理解在看源码时候是由于在使用@Component注解和@Autowired时注入的实例未初始化,这时候spring容器中接收不到未初始化的实例,这个解决方案,在注入的同时初始化这个实例让spring扫描到这个实例然后加入容器

    @Component
    public class ComponentClass {
    ​
        @Autowired
        private JedisClient jedisClient;
        public static ComponentClass componentClass;
        @PostConstruct
        public void init(){
            componentClass = this;
            componentClass.jedisClient = this.jedisClient;
        }
    }

    第二种:第二种事由于实例化的业务类在自己类种引用了spring容器种的实例类,这个时候实例化的类在堆内存种,而spring容器在自己的堆存种中,他们不在同一个堆中可能这是实例化失效的关键。

    以上都是小冷个人理解如有不同见解欢迎留言怼,有的源码小冷也是看的一知半解。

  • 相关阅读:
    冒泡排序的java实现
    linux磁盘挂载
    Spring第九篇:primary指定bean为首选对象
    Spring第八篇:容器中bean对象的创建顺序
    Spring第六篇:依赖的手动注入
    Spring第五篇:Spring bean的作用域
    Spring第四篇:bean实例的创建方式
    SpringBoot 整合 kaptcha 验证码
    Java 创建线程池的方式
    MySQL IF() 函数用法
  • 原文地址:https://www.cnblogs.com/qinyuanyuan/p/13406962.html
Copyright © 2011-2022 走看看