静态方法使用@Autowired注入

本文详细解析了Java中@Autowired注解的使用场景和注意事项,包括构造方法和静态方法中的使用,以及如何解决由此引发的NullPointerException异常。同时介绍了通过ApplicationContext、@PostConstruct注解和构造方法初始化静态变量的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java变量的初始化顺序为:静态变量或静态代码块–>实例变量或初始化代码块–>构造方法–>@Autowired(@Autowired:会在类的加载最后随着类的普通方法的需要注入,并且如果类中使用@Autowired注入的类中也使用@Autowired注解注入了用@Component、@Repository、@Service、@Controller修饰过交给Spring容器管理的类,那么也需要使用Spring容器或者applicationcontext上下文进行注入,手动实例化或者使用Java反射使用会失效,获得Null。)  允许多个相同的类@Autowired注入,但得到的是同一个实例,因为Bean是单例。

那么需要注意的点有两个,一.关于构造方法使用@Autowired的类,二.Static方法使用@Autowired的类

1.关于构造方法使用@Autowired的类

@Autowired
CategoryMapper categoryMapper;
 
private  List<Category> categoryList = categoryMapper.selectByExample(new CategoryExample());

这段代码报java.lang.NullPointerException: null异常。报错信息说:该类初始化时出错,出错原因是实例化bean时构造方法出错,在构造方法里抛出了空指针异常。

解决办法:

使用构造器注入的方法,明确了成员变量的加载顺序。如下

    private CategoryMapper categoryMapper;
    private  List<Category> categoryList;
 
    @Autowired
    public CategoryServiceImpl(CategoryMapper categoryMapper) {
        this.categoryMapper = categoryMapper;
        this.categoryList = categoryMapper.selectByExample(new CategoryExample());
    }

2.关于Static方法使用@Autowired的类的几种方法。

(1)使用ApplicationContext

package com.cn.common.util.EasyCaptcha;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * Title: SpringContextUtil
 * 
 * Description: 实现对spring context 的管理
 *
 * @author xiaojihuibengdi Date: 2019年6月5日 下午11:20:29
 */
@Component
public class SpringContextUtil implements ApplicationContextAware {

	private static ApplicationContext applicationContext;

	/**
	 * 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
	 */
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		SpringContextUtil.applicationContext = applicationContext;
	}

	/**
	 * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
	 */
	public static Object getBean(String name) {
		return applicationContext.getBean(name);
	}

	/**
	 * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
	 */
	public static <T> T getBean(Class<T> clazz) {
		return applicationContext.getBean(clazz);
	}

	/**
	 * 获取类型为requiredType的对象 如果bean不能被类型转换,相应的异常将会被抛出(BeanNotOfRequiredTypeException)
	 */
	public static <T> T getBean(String name, Class<T> requiredType) {
		return applicationContext.getBean(name, requiredType);
	}

	/**
	 * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
	 */
	public static boolean containsBean(String name) {
		return applicationContext.containsBean(name);
	}

	/**
	 * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。
	 * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
	 */
	public static boolean isSingleton(String name) {
		return applicationContext.isSingleton(name);
	}

	/**
	 * Class 注册对象的类型
	 */
	public static Class<?> getType(String name) {
		return applicationContext.getType(name);
	}

}

在使用的过程

package com.cn.common.util.EasyCaptcha;


import java.awt.Font;
import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.springframework.retry.RetryException;
import org.springframework.stereotype.Component;

import com.wf.captcha.Captcha;
import com.wf.captcha.GifCaptcha;
import com.wf.captcha.SpecCaptcha;



 /**
    *  验证码工具类
 * 
 *
 * @author wanghao
 */
@Component
public class CaptchaUtil {

    private static RedisCacheManager cacheManager = SpringContextUtil.getBean(RedisCacheManager.class);
	//	不要更改顺序,很重要!!!
    public static String verificationCode;
	
    // gif 类型验证码
    private static final int GIF_TYPE = 1;
    // png 类型验证码
    private static final int PNG_TYPE = 0;

    // 验证码图片默认高度
    private static final int DEFAULT_HEIGHT = 48;
    // 验证码图片默认宽度
    private static final int DEFAULT_WIDTH = 130;
    // 验证码默认位数
    private static final int DEFAULT_LEN = 5;

    public static void out(HttpServletRequest request, HttpServletResponse response) throws IOException {
        out(DEFAULT_LEN, request, response);
    }

    public static void out(int len, HttpServletRequest request, HttpServletResponse response) throws IOException {
        out(DEFAULT_WIDTH, DEFAULT_HEIGHT, len, null, request, response);
    }

    public static void out(int len, Font font, HttpServletRequest request, HttpServletResponse response) throws IOException {
        out(DEFAULT_WIDTH, DEFAULT_HEIGHT, len, null, font, request, response);
    }

    public static void out(int width, int height, int len, Integer vType, HttpServletRequest request, HttpServletResponse response) throws IOException {
        out(width, height, len, vType, null, request, response);
    }

    public static void out(int width, int height, int len, Integer vType, Font font, HttpServletRequest request, HttpServletResponse response) throws IOException {
        outCaptcha(width, height, len, font, GIF_TYPE, vType, request, response);
    }

    public static void outPng(HttpServletRequest request, HttpServletResponse response) throws IOException {
        outPng(DEFAULT_LEN, request, response);
    }

    public static void outPng(int len, HttpServletRequest request, HttpServletResponse response) throws IOException {
        outPng(DEFAULT_WIDTH, DEFAULT_HEIGHT, len, null, request, response);
    }

    public static void outPng(int len, Font font, HttpServletRequest request, HttpServletResponse response) throws IOException {
        outPng(DEFAULT_WIDTH, DEFAULT_HEIGHT, len, null, font, request, response);
    }

    public static void outPng(int width, int height, int len, Integer vType, HttpServletRequest request, HttpServletResponse response) throws IOException {
        outPng(width, height, len, vType, null, request, response);
    }

    public static void outPng(int width, int height, int len, Integer vType, Font font, HttpServletRequest request, HttpServletResponse response) throws IOException {
        outCaptcha(width, height, len, font, PNG_TYPE, vType, request, response);
    }
    
    /**
	 * Title: outCaptcha
	 * <p>
	 * Description: 获取验证码
	 * </p>
	 * 
	 * @author: wanghao
	 * @param request
	 * @param response
	 * @throws Exception void 返回类型
	 */
    private static void outCaptcha(int width, int height, int len, Font font, int cType, Integer vType, HttpServletRequest request, HttpServletResponse response) throws IOException {
        setHeader(response, cType);
        Captcha captcha = null;
        if (cType == GIF_TYPE) {
            captcha = new GifCaptcha(width, height, len);
        } else {
            captcha = new SpecCaptcha(width, height, len);
        }
        if (font != null) {
            captcha.setFont(font);
        }
        if (vType != null) {
            captcha.setCharType(vType);
        }
        HttpSession session = request.getSession();
        verificationCode = captcha.text().toLowerCase();
        captcha.out(response.getOutputStream());
    }

    //设置验证码相关信息    提供gif 或 png 两种格式
    public static void setHeader(HttpServletResponse response, int cType) {
        if (cType == GIF_TYPE) {
            response.setContentType("image/gif");
        } else {
            response.setContentType("image/png");
        }
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0L);
    }

}

 (2)使用注解@PostConstruct

@Component
public class Boo {

    private static Foo foo;
    @Autowired
    private Foo tFoo;

    @PostConstruct
    public void init() {
        Boo.foo = tFoo;
    }

    public static void randomMethod() {
         foo.doStuff();
    }
}

(3)利用构造方法

@Component
public class AA {

	private static Object variable;



	@Autowired
	public AA(Object variable) {
		AA.variable = variable;
	}
	
}

在spring进行组建注册的时候会进行初始化,初始化后赋值到变量,所以还有一个遗留问题,就是不能在构造器内调用静态变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值