不用注入方式使用Spring管理的对象中的方法,神奇

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

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

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

不用注入方式使用Spring管理的对象中的方法,神奇

不用注入方式使用Spring管理的对象中的方法,神奇

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

还有一种

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

不用注入方式使用Spring管理的对象中的方法,神奇

不用注入方式使用Spring管理的对象中的方法,神奇

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

不用注入方式使用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容器在自己的堆存种中,他们不在同一个堆中可能这是实例化失效的关键。

以上都是小冷个人理解如有不同见解欢迎留言怼,有的源码小冷也是看的一知半解。不用注入方式使用Spring管理的对象中的方法,神奇

不用注入方式使用Spring管理的对象中的方法,神奇