本文主要是介绍【SpringBoot】ApplicationContextAware 与 @Autowired 注解效果是一样,但是时机不一样,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、区别
- ApplicationContextAware 是一个接口,它提供一个方法 setApplicationContext ,当 spring 注册完成之后,会把 ApplicationContext 对象以参数的方式传递到方法里,在方法里我们可以实现自己的逻辑,去获取自己的 bean,当前对接的断言等;一般用在被封装的工具包, starter 包中,方便给其它开发人员调用。
- @Autowired 是直接给开发人员使用的,直接注入对接类型的 bean 的,开箱即用,对应的注解还有 @Qualifier,或者直接使用 @Resource 注解来实现按 beanName 的注入。
二、案例
1、LindContext 组件
@Component
public class LindContext {public void print() {System.out.println("lind-context print.");}}
2、LindAware 组件
/*** 获取 spring 容器,以访问容器中定义的其它 bean*/
@Component
@Slf4j
public class LindAware implements ApplicationContextAware {// Spring 应用上下文环境private static ApplicationContext applicationContext;private LindContext lindContext;public void contextPrint() {this.lindContext.print();}/*** 重写接口的方法,该方法的参数为框架自动加载的IOC容器对象* 该方法在启动项目的时候会自动执行,前提是该类上有IOC相关注解,例如@Component* @param applicationContext ioc容器* @throws BeansException e*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {// 将框架加载的ioc赋值给全局静态iocLindAware.applicationContext = applicationContext;if (LindAware.applicationContext.geetBeansOfType(LindContext.class).isEmpty()) {throw new IllegalArgumentException("未加载或者未发现 LindContext 的 bean,请保证它可以正常加载到 spring 容器。")}this.lindContext = LindAware.applicationContext.getBean(LindContext.class);log.info("==================ApplicationContext加载成功==================");}//获取applicationContextpublic static ApplicationContext getApplicationContext() {return applicationContext;}/*** 获取对象* @param name* @return Object 一个以所给名字注册的 bean 的实例(service 注解方式,自动生成以首字母小写的类名为 bean name)*/public static Object getBean(String name){return getApplicationContext().getBean(name);}//通过class获取Bean.public static <T> T getBean(Class<T> clazz){return getApplicationContext().getBean(clazz);}//通过name,以及Clazz返回指定的Beanpublic static <T> T getBean(String name,Class<T> clazz){return getApplicationContext().getBean(name, clazz);}
}
3、controller
public class HelloController {@Autowiredprivate LindAware lindAware;@PostMapping("/test2")public String test2() {lindAware.contextPrint();return "test2 aware success!";}}
4、测试接口
localhost:8080/testUtils/test2
返回结果:
"test2 aware success!"
三、总结
- 如果将 LindContext 类中 @Component 注解去掉,没有将该 bean 注册到 spring 容器时,调用接口时会在 LindAware 中抛出对应的异常,来提示给开发人员
- 如果将 LindAware 类中 this.lindContext = LindAware.applicationContext.getBean(LindContext.class); 去掉,调用接口时,会报空指针异常,原因是 LindAware 类中 lindContext 是 null,LindContext 该 bean 没有注入到 LindAware 类中。
java.lang.NullPointerException: nullat com.example.demo.utils.LindAware.contextPrint(LindAware.java:25) ~[classes/:na]at com.example.demo.controller.HelloController.test2(HelloController.java:32) ~[classes/:na]
- 如果将 LindAware 类中 this.lindContext = LindAware.applicationContext.getBean(LindContext.class); 去掉,在 private LindContext lindContext; 添加上 @Autowired 注解,那么调用接口,是能正常返回结果的。
- 通过 ApplicationContextAware 拿到的 ApplicationContext,和通过 @Resource 或者 @Autowired 拿到的 ApplicationContext,效果是一样的,时机不一样,但是ApplicationContext只有一个。
四、参考文档
springboot~ApplicationContextAware与@Autowired注解
这篇关于【SpringBoot】ApplicationContextAware 与 @Autowired 注解效果是一样,但是时机不一样的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!