1.问题描述
我们平时使用@Autowired注入对象时,一般被注入的类都带有@Coponent、@Controller、@Service 、@repository等注解才可以。注入类和被注入类都被spring所管理,可以完成调用。但是当非容器类(没加以上注解时)使用@Autowired调用容器中的类时,注入对象为空,报空指针异常
HelloService为加入容器中的类
BeanUtil为未加入容器的类,调用HelloService会报空指针异常
2.问题解决
创建工具类BeanUtils,在这个工具类中的getBean可以得到容器中的类,在非容器类中使用
@Component
public class BeanUtils implements ApplicationContextAware {
/**
* 以静态变量保存ApplicationContext,可在任意代码中取出ApplicaitonContext.
*/
private static ApplicationContext context;
/**
* 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
*/
@Override
public void setApplicationContext(ApplicationContext context) {
BeanUtils.context = context;
}
public static ApplicationContext getApplicationContext() {
return context;
}
/**
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. 方法返回值的类型由调用者决定
*/
public static <T> T getBean(String name) {
return (T) context.getBean(name);
}
/// 获取当前环境
public String getActiveProfile() {
return context.getEnvironment().getActiveProfiles()[0];
}
}
非容器类中使用容器中的类
public class StationFactory {
Map<String, StationOperation> map = new HashMap<>();
{
map.put("定损中心主管指标表", BeanUtils.getBean("leadDSZXOperation"));
map.put("定损中心员工指标表", BeanUtils.getBean("empDSZXOperation"));
map.put("视频查勘中心主管指标表",BeanUtils.getBean("leadVideoSurveyCenterOperation"));
map.put("视频查勘中心员工指标表",BeanUtils.getBean("empVideoSurveyCenterOperation"));
map.put("视频定损中心主管指标表",BeanUtils.getBean("leadVideoDSCenterOperation"));
}
}
3.@Autowired注意事项
1、使用@Autowired的当前类也必须由spring容器托管(打@Coponent、@Controller、@Service 、@repository)
2、不管是public 和 private 修饰的字段都可以自动注入
3、默认情况下,使用@Autowired注解的属性一定要被装配,如果在容器中找不到该类型的bean注入,就会报错。如果允许不被装配就可以将@Autowired的required属性为false
4、@Autowired 是基于类型的注入,如果当前类型属性在容器中只有一个Bean, 那么属性名不限制,但一般建议遵循类名首字母小写的规则‘
5、如果当前属性类型在容器中有个多个Bean,那么必须要通过属性名 或者 @Qualifier 指定Bean name