静态方法中直接使用注入的bean对象

问题:静态方法中注入bean
分析问题:先看一段代码



@Component
public class ScriptExecuteContent {

@Autowired
private static SignRepository signRepository;

public static String checkSign(String certNo, String acctNo, String instCode) {
    Sign sign = signRepository.findByCertNoAndAcctNoAndInstCode(certNo, acctNo, instCode);
    if (null != sign
            && StringUtils.equals(sign.getStatus(), StatusEnum.SUCCESS.code())
            && DateUtil.getCurrentDate().before(sign.getExpireTime())) {
        return "1";
    } else {
        return "0";
    }
}

}



该段代码晃眼一看没啥问题,但是运行就会null异常,因为此处注入的signRepository为null,这是因为静态方法是属于类的,普通方法才属于对象,spring注入是在容器中实例化变量的,并且静态是优先于对象存在的,所以直接在静态方法中调用注入的静态变量其实是为null的,针对这点不太明白的,可以自行补一下java基础。
但是现实当中我们很多情况需要再静态方法中调用注入的bean对象,要怎么样实现呢?我目前知道的有两种方法。

解决问题:
1. @Autowired 用在构造函数上
我们知道@Autowired 注释,可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作,此种方式就是在构造函数上使用@Autowired。
代码参考:



@Component
public class ScriptExecuteContent {

private static SignRepository signRepository;

@Autowired
public ScriptExecuteContent(SignRepository signRepository) {
    ScriptExecuteContent.signRepository = signRepository;
}

public static String checkSign(String certNo, String acctNo, String instCode) {
    Sign sign = signRepository.findByCertNoAndAcctNoAndInstCode(certNo, acctNo, instCode);
    if (null != sign
            && StringUtils.equals(sign.getStatus(), StatusEnum.SUCCESS.code())
            && DateUtil.getCurrentDate().before(sign.getExpireTime())) {
        return "1";
    } else {
        return "0";
    }
}

}



2. 使用 @PostConstruct 注解
@PostConstruct是Java EE 5引入来影响Servlet生命周期的注解,被用来修饰非静态的void()方法,@PostConstruct在构造函数之后执行,init()方法之前执行。
代码参考:



@Component
public class ScriptExecuteContent {

@Autowired
private SignRepository signRepository;

private static ScriptExecuteContent scriptExecuteContent;

@PostConstruct
public void init() {
    scriptExecuteContent = this;
    scriptExecuteContent.signRepository = this.signRepository;
}

public static String checkSign(String certNo, String acctNo, String instCode) {
    Sign sign = scriptExecuteContent.signRepository.findByCertNoAndAcctNoAndInstCode(certNo, acctNo, instCode);
    if (null != sign
            && StringUtils.equals(sign.getStatus(), StatusEnum.SUCCESS.code())
            && DateUtil.getCurrentDate().before(sign.getExpireTime())) {
        return "1";
    } else {
        return "0";
    }
}

}



总结:以上两种方式都能实现静态方法中直接使用注入的bean对象,实现方式肯定不止这两种,自己基础差了,目前只知道这两种。

原文地址:http://blog.51cto.com/zhengjiang/2141118

时间: 2024-10-27 18:51:26

静态方法中直接使用注入的bean对象的相关文章

JSP中使用Spring注入的Bean时需要注意的地方

遇到问题 遇到一个问题:在JSP中,使用Spring注入的Bean对象时,未能正确地获取到想要的对象. 郁闷的是,它也没报错. 研究问题 使用DEBUG功能(好久不在JSP里写Java代码了,都忘了JSP也可以打断点调试),跟踪了一下代码,发现确实有了我想使用的类的实例,不过是个代理类. 想到反射.代理相关的知识,貌似知道问题在哪了. 赶紧试了一下,果然…… 解决 在JSP里你要获得的Bean对象的类型,要定义成接口类,而不是实现类. 当然,这也视情况而定,我不确定,在JSP里使用Spring注

静态方法中不能new内部类的实体对象

原因如下: 1.内部类可以访问外部类的成员变量 2.对象创建完成后对象的成员变量才会被分配空间 3.main的静态方法执行时可以不存在外部类,不创建实体对象 4.内部类能访问成员变量意味着一定存在外部类实体对象 因为3和4矛盾,所以在静态方法中不能new内部类的实体对象 这个是错误的 class demo{        public void func(){        //位置1:    }    class Inner{}        public static void main(S

Mybatis根据数据库中的表自动生成Bean对象与Mapper文件 (小白式教程)

示例IDE采用 IDEA //**********************华丽的分割线****************// 1.新建一个java项目-->在Src目录下创建3个包(Package)与一个文件夹(Directory) Package(包)- ①bean:存放自动生成的Java Bean ②mapper:存放自动生成的mapper接口与对应的.xml文件 ③test:存放一个main方法用于执行自动生成操作 Directory(目录):: lib:存放项目所需要导入的包 2.向lib

【Spring源码--IOC容器的实现】(五)Bean对象的创建

前言: 1.第一次直接用CSDN原生的编辑器写博客,格式排版还有点陌生,见谅. 2.前面的文章我们写了IOC容器的启动,也就是把xml里面的配置都解析成Spring的内部结构BeanDefinition,并存储在Spring的容器中.下面我们将分析IOC容器室怎样对bean的依赖关系进行注入的.依赖注入的过程是第一次向IOC容器索要bean时触发的(例外:lazy-init实现bean的预实例化),也就是getBean方法. 3.依赖注入可以分为两个过程,一是bean所包含的Java对象的创建,

复现一个典型的线上Spring Bean对象的线程安全问题(附三种解决办法)

问题复现 假设线上是一个典型的Spring Boot Web项目,某一块业务的处理逻辑为: 接受一个name字符串参数,然后将该值赋予给一个注入的bean对象,修改bean对象的name属性后再返回,期间我们用了 Thread.sleep(300) 来模拟线上的高耗时业务 代码如下: @RestController @RequestMapping("name") public class NameController { @Autowired private NameService n

在Servlet中可访问Spring bean对象,但是不能直接以注入的方式引用

在Servlet中使用注解的方式引用Spring bean对象,会报空指针,因此可以在init()方法中通过WebApplicationContextUtils.getWebApplicationContext(servletContext)获取Spring, 代码如下: package zttc.itat.user.servlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; impor

非spring组件servlet、filter、interceptor中注入spring bean

问题:在filter和interceptor中经常需要调用Spring的bean,filter也是配置在web.xml中的,请问一下这样调用的话,filter中调用Spring的某个bean,这个bean一定存在吗?现在总是担心filter调用bean的时候,bean还没被实例化? 答案:因为spring bean.filter.interceptor加载顺序与它们在 web.xml 文件中的先后顺序无关.即不会因为 filter 写在 listener 的前面而会先加载 filter.最终得出

【Spring实战】注入非Spring Bean对象

大家经常用到Spring IOC去管理对象之间的依赖关系,但一般情况下都有一个前提:这些Bean对象必须是通过Spring容器创建实例化的. 但实际上,项目中有可能会遇到这样的场景: 一个类不是通过Spring容器实例化的,而是直接new Object()这种方式创建,这个对象又和别的Spring容器中管理的对象存在依赖关系. 这时该怎么办呢,当然,我们可以手动的去调用setXxxx()方法去设置对象之间的依赖,但这样耦合性又太高.还好Spring也提供了注入非Spring Bean对象的功能.

Spring中bean对象的生命周期

Spring提供了一些接口来提供一些方法,体现了bean对象在Spring容器中的生命周期 具体的过程可以体现为: 读取权限类名->构建一个类对象->用这个类对象通过无参构造器newInstance()构建对象 ↓ 调用set方法注入依赖 ↓ 如果这个Bean已经实现了BeanNameAware接口 调用它实现的setBeanName(String name)方法 此处传递的就是Spring配置文件中Bean的name值 ↓ 如果这个Bean已经实现了BeanFactoryAware接口 容器