静态方法使用@Autowired注入

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

静方法使用@Autowired注解时,需要注意以下几点: 1. 静态方法不能直接使用@Autowired注解来注入依赖的类,因为@Autowired注解是基于实例对象的依赖注入机制。在静态方法中,无法直接访问实例变量和实例方法。 2. 如果在静态方法中需要使用被容器管理的类,可以通过将该类作为静态变量,并在静态方法中进行访问。例如,在Spring框架中,可以使用@Component注解将类标记为被容器管理的组件,然后在静态方法中通过静态变量来访问该组件。 3. 静态方法使用@Autowired注解注入的类,需要在类加载的最后进行注入,同时需要确保被注入的类也被标记为被容器管理的组件。这样才能保证在静态方法中正确地访问到被注入的实例。 总结起来,静态方法使用@Autowired注解需要注意的是,不能直接使用@Autowired注入依赖的类,而是需要将被注入的类作为静态变量,并在静态方法中访问该变量。同时,需要确保被注入的类被标记为被容器管理的组件,以保证注入的正确性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [静态方法使用@Autowired注入](https://blog.csdn.net/wh710107079/article/details/98183733)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [@Autowired注解和静态方法](https://blog.csdn.net/weixin_34414650/article/details/93619433)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值