@component无法注入_不用注入方式使用Spring管理的对象,神奇

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

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

a7e2384b94981c7f835c21a377a1842c.png

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

ede9da021b8d10a7242ce4b315fa8081.png

e42a9819dea18a09aa2e269084b89585.png

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

还有一种

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

68840965184818b7b41303b4af93d885.png

fe3d0a53696fbff7fac659e8544b01e5.png

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

8f5abc54d5c4a1fcf0c44e03888fe96f.png

综上所述只有第三种方法可以,这个里附上加载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;@Componentpublic 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 getBean(Class clazz) {              return getApplicationContext().getBean(clazz);       }       //通过name,以及Clazz返回指定的Bean       public static T getBean(String name, Class clazz) {              return getApplicationContext().getBean(name, clazz);       }}

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

这里小冷按自己理解说一下为啥前两种方式无法使用,如有不同理解和更为准确的解释欢迎私信留言!!!!

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

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

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

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

23335edab1e262ac0a85b5b008261603.png

41f261ee4fc806e9c3f86a400913dbda.png

852049cf1f7d799a9564566d29763469.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值