欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringContextHolder使用报错及@Lazy使用

程序员文章站 2022-05-21 22:11:36
...
  • 今天在使用SpringContextHolder来获取一个bean的时候出现错误,报错如下:
java.lang.IllegalStateException: applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder.
	at org.apache.commons.lang3.Validate.validState(Validate.java:826)
	at com.jituan.common.util.SpringContextHolder.assertContextInjected(SpringContextHolder.java:79)
	at com.jituan.common.util.SpringContextHolder.getBean(SpringContextHolder.java:41)
	at com.jituan.common.message.util.sms.SmsUtil.querySmsTemplate(SmsUtil.java:206)
	at com.jituan.common.message.util.sms.SmsUtil.send(SmsUtil.java:76)
	at com.jituan.common.message.processer.SmsProcesser.send(SmsProcesser.java:37)
	at com.jituan.batch.msghandler.MessageHandler.smsSend(MessageHandler.java:106)
	at com.jituan.batch.msghandler.MessageHandler$SmsTread.run(MessageHandler.java:185)
  • 解决方案:
  1. 在spring-mvc.xml中加入配置后解决(主动注入springContextHolder):
<!-- 全局变量以便可以获得对应的注入bean -->
	<bean id="springContextHolder" class="com.jituan.common.util.SpringContextHolder" />
  1. 在SpringContextHolder类上加入注解@Service、@Lazy(false)
  • SpringContextHolder 具体实现
import java.util.Map;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
 
/**
 *
 *以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候中取出ApplicaitonContext.
 * @author Bucky
 */
@Service
@Lazy(false)
public class SpringContextHolder implements ApplicationContextAware{
 
    private static ApplicationContext applicationContext;
 
     
    //实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
    public void setApplicationContext(ApplicationContext applicationContext) {
        SpringContextHolder.applicationContext = applicationContext;
    }
 
    
    //取得存储在静态变量中的ApplicationContext.
    public static ApplicationContext getApplicationContext() {
        checkApplicationContext();
        return applicationContext;
    }
     
    //从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) {
        checkApplicationContext();
        return (T) applicationContext.getBean(name);
    }
 
     
    //从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
    //如果有多个Bean符合Class, 取出第一个.
    @SuppressWarnings("unchecked")
    public static <T> T getBean(Class<T> clazz) {
        checkApplicationContext();
        @SuppressWarnings("rawtypes")
                Map beanMaps = applicationContext.getBeansOfType(clazz);
        if (beanMaps!=null && !beanMaps.isEmpty()) {
            return (T) beanMaps.values().iterator().next();
        } else{
            return null;
        }
    }
 
    private static void checkApplicationContext() {
        if (applicationContext == null) {
            throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");
        }
    }
 
}
  • @Lazy注解用于指定该Bean是否取消预初始化。主要用于修饰Spring Bean类,用于指定该Bean的预初始化行为lazy代表延时加载。
    1.lazy=false,代表不延时,如果对象A中还有对象B的引用,会在A的xml映射文件中配置b的对象引用,多对一或一对多,不延时代表查询出对象A的时候,会把B对象也查询出来放到A对象的引用中,A对象中的B对象是有值的。
    2.lazy=true代表延时,查询A对象时,不会把B对象也查询出来,只会在用到A对象中B对象时才会去查询,默认好像是false,你可以看看后台的sql语句的变化就明白了,一般需要优化效率的时候会用到。