Spring—无法获取@Service和@Autowired注解注入的Bean

异常截图

在使用@Service、@Autowired注解标注的bean组件时,出现空指针异常,如图:

Spring—无法获取@Service和@Autowired注解注入的Bean_第1张图片 异常截图​​

解决思路

  • 通过spring提供的ApplicationContext组件将spring容器中已经注入的bean组件输出,查看是否正确注入了bean组件;
  • 如果正确注入,那说明拿取bean组件的姿势不对;
  • 如果未正确注入,那说明自动注入的相关配置及注解使用姿势不对;

解决过程

  • 一.在开始之前,我想先啰嗦一个概念,请各位看客老爷再没有耐心,也要看一看。
  • 想要获取交由spring容器管理的bean组件,必须从spring容器中获取。
  • 换句话说,spring容器有一个上下文,只要能拿到这个上下文,就能拿到spring的所有内容。但是呢,spring有爱情洁癖,如果你一开始不选择她,那么她就什么都不会给你。(上下文=心,所有内容=财产)

通过ApplicationContext获取已经注入的全部组件之直接上代码

  • SpringJobBeanFactory类,实现了ApplicationContextAware接口;
  • Test类,加载spring配置文件,输出spring容器中的bean
package com.lansoft.isp.start;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringJobBeanFactory implements ApplicationContextAware {

    
    private static ApplicationContext applicationContext;
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringJobBeanFactory.applicationContext=applicationContext;
        
    }
     public static ApplicationContext getApplicationContext() {
            return applicationContext;
    }
    @SuppressWarnings("unchecked")
    public static  T getBean(String name) throws BeansException {
            if (applicationContext == null){
                return null;
            }
            return (T)applicationContext.getBean(name);
      }
    
    public static  T getBean(Class  name) throws BeansException {
            if (applicationContext == null){
                return null;
            }
            return applicationContext.getBean(name);
      }
}
  • @Component是将当前对象标注为交由spring管理的组件,很重要,必要;
  • 必须实现ApplicationContextAware接口;

解释说明:

实现了ApplicationContextAware接口,就表示得到了spring容器的心,而@Component则表示你在一开始就选择了她。

package com.lansoft.isp.start;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

	private static Logger _log = LoggerFactory.getLogger(Test.class);
			
	public static void main(String[] args) {
		_log.info(">>>>> isp-service-ipran 正在启动 <<<<<");
		new ClassPathXmlApplicationContext("classpath:spring/*.xml");
		_log.info(">>>>> isp-serwenvice-ipran 启动完成 <<<<<");
		//获取全部bean组件
		String[] beanDefinitionNames = SpringJobBeanFactory.getApplicationContext().getBeanDefinitionNames();
		for(String bean:beanDefinitionNames){
			System.out.println(bean);
		}
	}
}

如果正常配置的话,启动后会将spring中的bean组件全部输出,我只有一个,输出如下:

abcTestService

正常输出,说明组件装配成功,获取组件的姿势不对

1.原因分析:

参考上面案例讲的,如果第一次使用的组件不是spring中的组件,那么他就不会把自己管理的东西交给你

2.检查代码:

查看代码中使用初次使用的容器,是否是通过new的方式获取的,如果是,那完犊子;[手动旺柴脸]

3.解决方案:

使用@Component注解+实现ApplicationContextAware来获取spring中的bean组件,具体请参考上面SpringJobBeanFactory类

package com.lansoft.isp.start;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.lansoft.isp.api.bus.AbcTestService;

public class Test {

	private static Logger _log = LoggerFactory.getLogger(Test.class);
			
	public static void main(String[] args) {
		_log.info(">>>>> isp-service-ipran 正在启动 <<<<<");
		new ClassPathXmlApplicationContext("classpath:spring/*.xml");
		_log.info(">>>>> isp-serwenvice-ipran 启动完成 <<<<<");
		//获取全部bean组件
//		String[] beanDefinitionNames = SpringJobBeanFactory.getApplicationContext().getBeanDefinitionNames();
//		for(String bean:beanDefinitionNames){
//			System.out.println(bean);
//		}
		//从spring容器中获取bean组件
		AbcTestService bean = SpringJobBeanFactory.getBean("abcTestService");
		String test = bean.testAutowired();
		System.out.println(test);
	}
}

没有输出,说明配置有问题,需要检查配置以及使用的注解

这种情况属于配置问题,请自行百度,在此不多啰嗦

本章博客的重点:

spring容器管理的bean组件位于一个密闭的容器里面,通过new的方式没有办法获取到spring中的bean组件;

解决办法

1.实现ApplicationContextAware

2.增加@Component注解


你好,我叫吕小布。博客中部分解释仅供参考,纯碎是因为这么好记,不负责。

 

你可能感兴趣的:(spring,java基础)