在项目中有时需要根据需要在自己new一个对象,或者在某些util方法或属性中获取Spring Bean对象,从而完成某些工作,但是由于自己new的对象和util方法并不是受Spring所管理的,如果直接在所依赖的属性上使用@Autowired就会报无法注入的错误,或者是没报错,但是使用的时候会报空指针异常。总而言之由于其是不受IoC容器所管理的,因而无法注入。

        Spring提供了两个接口:BeanFactoryAware和ApplicationContextAware,这两个接口都继承自Aware接口。如下是这两个接口的声明:

public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
public interface ApplicationContextAware extends Aware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

       在Spring官方文档中描述,在初始化Spring bean时,如果检测到某个bean实现了这两个接口中的一个,那么就会自动调用该bean所实现的接口方法。这里可以看到,这两个方法都是将IoC容器管理bean的工厂对象传递给当前bean,也就是说如果我们在当前bean中将工厂对象保存到某个静态属性中,那么我们就能够通过工厂对象获取到我们需要的bean。如下是使用ApplicationContextAware实现的一个SpringBeanUtil:

public class SpringBeanUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
SpringBeanUtil.applicationContext = applicationContext;
} public static <T> T getBean(Class<T> clazz) {
return (T) applicationContext.getBean(clazz);
} public static Object getBean(String name) throws BeansException { return applicationContext.getBean(name);
}
}

       这里还需要在配置文件中指定创建当前类的一个实例:

<bean id="springBeanFactory" class="com.business.util.SpringBeanUtil"/>

       可以看到,我们再SpringBeanUtil中声明了一个ApplicationContext类型的静态属性,并且在setApplicationContext()方法中将获取到的ApplicationContext赋值给了该静态属性,这样我们就可以在另外两个声明的静态方法中通过ApplicationContext获取IoC容器所管理的bean了。如下是一个测试示例:

public class ClassRoom {
public void describeStudent() {
Student student = SpringBeanUtil.getBean(Student.class);
System.out.println(student);
} public static void describeClassRoomCapacity() {
Student student = SpringBeanUtil.getBean(Student.class);
System.out.println("Is it not empty? " + (null != student));
}
}
public class Student {
@Override
public String toString() {
return "I am a student.";
}
}
<bean id="springBeanFactory" class="com.util.SpringBeanUtil"/>
<bean id="student" class="com.domain.Student"/>

如下是驱动类:

public class BeanApp {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("com/resources/application.xml");
ClassRoom.describeClassRoomCapacity();
ClassRoom classRoom = new ClassRoom();
classRoom.describeStudent();
}
}

       在驱动类中,我们首先使用ClassPathXmlApplicationContext加载配置文件中的bean。可以看到,我们创建了一个SpringBeanUtil和一个Student的bean。我们首先在静态方法中获取了Student实例,并将其打印出来了,我们也在new出来的ClassRoom实例中通过SpringBeanUtil获取了Student实例,并且对其进行了输出。如下是输出结果:

Is it not empty? true
I am a student.

        可以看到,无论是在静态方法中,还是在手动new的实例中,我们都成功获取了IoC容器所管理的bean。如果我们想在静态属性中获取SpringBean,其实也非常简单,直接对属性赋值即可,如下所示:

private static Student student = SpringBeanUtil.getBean(Student.class);

如何在静态方法或非Spring Bean中注入Spring Bean的更多相关文章

  1. 在非spring组件中注入spring bean

    1.在spring中配置如下<context:spring-configured/>     <context:load-time-weaver aspectj-weaving=&q ...

  2. spring中如何向一个单例bean中注入非单例bean

    看到这个题目相信很多小伙伴都是懵懵的,平时我们的做法大都是下面的操作 @Component public class People{ @Autowired private Man man; } 这里如 ...

  3. Java(多)线程中注入Spring的Bean

    问题说明 今天在web应用中用到了Java多线程的技术来并发处理一些业务,但在执行时一直会报NullPointerException的错误,问题定位了一下发现是线程中的Spring bean没有被注入 ...

  4. 【转】Java(多)线程中注入Spring的Bean

    问题说明 今天在web应用中用到了Java多线程的技术来并发处理一些业务,但在执行时一直会报NullPointerException的错误,问题定位了一下发现是线程中的Spring bean没有被注入 ...

  5. 获取并打印Spring容器中所有的Bean名称

    思路: 1.实现Spring的ApplicationContextAware接口,重写setApplicationContext方法,将得到的ApplicationContext对象保存到一个静态变量 ...

  6. Spring Framework------>version4.3.5.RELAESE----->Reference Documentation学习心得----->Spring Framework中的spring web MVC模块

    spring framework中的spring web MVC模块 1.概述 spring web mvc是spring框架中的一个模块 spring web mvc实现了web的MVC架构模式,可 ...

  7. Spring Boot中使用 Spring Security 构建权限系统

    Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,为应用系统提供声明式的安全 ...

  8. 通过spring.net中的spring.caching CacheResult实现memcached缓存

    通过spring.net中的spring.caching CacheResult实现memcached缓存1.SpringMemcachedCache.cs2.APP.config3.Program. ...

  9. Spring Boot动态注入删除bean

    Spring Boot动态注入删除bean 概述 因为如果采用配置文件或者注解,我们要加入对象的话,还要重启服务,如果我们想要避免这一情况就得采用动态处理bean,包括:动态注入,动态删除. 动态注入 ...

随机推荐

  1. cmdb截图

  2. 新浪微博资深大牛全方位剖析 iOS 高级面试

    第1章 课程简介本章对这门课程所讲述内容进行概要介绍,其中包括课程目标.适合人群,课程特色.课程收获.课程安排等.整个课程学习完结后,有机会获得电话模拟面试及内推. 1-1 课前必读(不看会错过一个亿 ...

  3. Spring源码分析(一)基本介绍

    摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 前言 作为一名开发人员,阅读源码是一个很好的学习方式.本文将结合< ...

  4. 设计一个分布式RPC框架

    0 前言 提前先祝大家春节快乐!好了,先简单聊聊. 我从事的是大数据开发相关的工作,主要负责的是大数据计算这块的内容.最近Hive集群跑任务总是会出现Thrift连接HS2相关问题,研究了解了下内部原 ...

  5. 一个C语言内存管理模块的实现

    C 内存管理模块的编写 C语言手动管理内存很困难,有时候很难发现内存泄漏,这两天看了一下里面有写了一个简单的内存管理模块,发现挺精巧,可以有效检测内存泄漏 原理很简单,就是把C的malloc函数分配的 ...

  6. 在myeclipse等IDE中添加本地的dtd与schema约束文件

      *针对没有网络无法正确引入dtd而使用不了提示的问题 (配置完后重启IDE)   window->perferences- > 搜索xml c 找到xml catalog 右边点击 a ...

  7. 使用HDFS来进行线上应用的文件存储

    使用HDFS来进行线上应用的文件存储 分类: 云计算2011-07-06 17:57 721人阅读 评论(0) 收藏 举报 hadoop任务集群存储数据分析服务器 这段时间公司使用的hadoop组件h ...

  8. 2017-2018-1 20155330 《信息安全系统设计基础》第10周课堂测试&课下作业

    2017-2018-1 20155330 <信息安全系统设计基础>第10周课堂测试&课下作业 stat命令的实现-mysate 学习使用stat(1),并用C语言实现 提交学习st ...

  9. 【CJOJ2433】陌上花开 树状数组套替罪羊树

    [CJOJ2433]陌上花开 树状数组套替罪羊树 蛤?bzoj?没权限QAQ 蛤?CDQ?看了好久没看懂QwQ 好吧我会拿cdq再写一遍的 为啥我感觉这东西比cdq好写 只好拿树状数组套替罪羊树水水了 ...

  10. Kali2.0可用国内源更新sources.list

    vim /etc/apt/sources.list #中科大 deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contri ...