上篇文章《ApplicationContextAwareProcessor源码解析 + Aware接口简介》简单地介绍了Aware接口,本篇文章将介绍一下Aware的使用方法,由于spring中的Aware众多,这里仅仅抛砖引玉,本篇文章会介绍如下几个Aware:
下面对其进行一一介绍。
源码地址:
sc.springstudy.c072_bean_life_cycle.beans;import org.springframework.beans.factory.BeanNameAware;
import t.EmbeddedValueResolverAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringValueResolver;/**** Description:* 实现了BeanNameAware,可以获取到当前bean在IOC容器中的名字* 注意该Aware的调用在前置处理器applyBeanPostProcessorsBeforeInitialization方法之前** 实现了EmbeddedValueResolverAware,可以利用resolver来解析字符串表达式(el表达式)*/
@Component
public class Tiger implements BeanNameAware, EmbeddedValueResolverAware {private String name = "老虎";public void setBeanName(String name) {println("当前bean的名字为:" + name);}public void setEmbeddedValueResolver(StringValueResolver resolver) {String val = solveStringValue("当前系统为${os.name},表达式3*8的结果为:#{3*8}");println("解析后的字符串为===" + val);}
}
测试效果如下:
源码地址:
实际项目中应该会遇到这种情况,我们引入了某个jar,该jar里有些bean会随着项目的启动注入到IOC容器里。
如果我们想使用这些bean时,或许很多时候都可以通过@Autowired的方式将其注入到我们自己的bean对象里去使用他们。
但是某些时候,我们却不能这样做,比如说某个工具类要使用这样的bean,如果使用了@Autowired的方式将依赖的bean注入到该工具类,那该工具类就得暴漏成一个bean注入到IOC容器,那别人使用这个工具类时就得通过@Autowired的方式将该工具类注入到要使用该工具类的bean对象里,这其实是很难让人接受的。
而且在多态的情况下,我们往往不知道真正要调用的是哪个具体的类,这时候想用@Autowired都没法用
所以在真实项目开发中我们往往需要一个IOC容器的引用,然后通过该引用随时随地的获取IOC容器中具体的bean对象,如:3.2中的Utils。
sc.elegant.util;ums.ResultEnum;
ption.ElegantCheckedException;
import org.springframework.beans.BeansException;
import t.ApplicationContext;
import t.ApplicationContextAware;
import org.springframework.stereotype.Component;/**** @author : Sun Chuan* @date : 2019/11/19 15:08* Description: 通过静态方法获取IOC容器中bean实例的方法*/
@Component
public class ApplicationContextUtils implements ApplicationContextAware {/**** spring启动后会将IOC容器的引用赋值给application * 静态变量不会被JVM回收,* 所以可以通过静态方法getBeanByType 和 getBeanByName随时获取项目中IOC容器内的bean*/private static ApplicationContext applicationContext;private ApplicationContextUtils() {}@Overridepublic void setApplicationContext(ApplicationContext context) throws BeansException {applicationContext = context;}/**** 从IOC容器中根据类型拿bean实例* @param clazz* @param <T>* @return* @throws Exception*/public static <T> T getBeanByType(Class<T> clazz) throws ElegantCheckedException {if (applicationContext == null) {throw new ElegantCheckedException(ResultEnum.FAILURE);}Bean(clazz);}/**** 从IOC容器中根据beanName拿bean实例* @param beanName* @param <T>* @return* @throws Exception*/public static <T> T getBeanByName(String beanName) throws ElegantCheckedException {if (applicationContext == null) {throw new ElegantCheckedException(ResultEnum.FAILURE);}return (T) Bean(beanName);}
}
源码地址:
纯spring版:
springboot版:
对这个Aware印象还是比较深刻的,因为很久之前做过一个安哥拉的项目,项目需要进行葡萄牙语、英语和中文的切换,当时进行标签国际化就用到了它。这里简单介绍一下在spring环境下MessageSourceAware的使用方式。
使用场景 :
项目启动时
不同环境加载不同的配置。
sc.springstudy.c072_bean_fig;
import t.annotation.Bean;
import t.annotation.ComponentScan;
import t.annotation.Configuration;
import t.support.ResourceBundleMessageSource;@Configuration
@ComponentScan(value = sc.springstudy.c072_bean_life_cycle")
public class C072Config {/**** 向IOC容器中注入ResourceBundleMessageSource* 该类用来确定properties的位置、设置编码格式等* 注意 : spring规定这个bean的name必须叫----> messageSource** @return*/@Bean(value = "messageSource")public ResourceBundleMessageSource resourceBundleMessageSource() {ResourceBundleMessageSource resourceBundleMessageSource = new ResourceBundleMessageSource();//设置properties的路径---注意最后一个messages不能少,它指的是properties文件的前缀resourceBundleMessageSource.setBasename("i18/messages/messages");resourceBundleMessageSource.setDefaultEncoding("utf-8");return resourceBundleMessageSource;}
}
这种使用方式的应用场景主要为:项目启动时不同环境加载不同的配置
sc.springstudy.c072_bean_life_cycle.beans;import t.MessageSource;
import t.MessageSourceAware;
import org.springframework.stereotype.Component;import java.util.Locale;/*** @author : Sun Chuan* @date : 2019/11/24 11:13* Description:*/
@Component
public class MessageSourceDemo implements MessageSourceAware {public void setMessageSource(MessageSource messageSource) {String aaa = Message("hello", null, Default());String bbb = Message("hello", null, Locale.CHINA);String ccc = Message("hello", null, Locale.US);println(aaa);println(bbb);println(ccc);}
}
启动项目,可以发现已经解析到了不同properties文件里hello对应的值
使用场景: 使用注入MessageSource的方式,可以直接获取配置文件里key对应的value,这种情况下使用场景就可以自己发挥了。
如有如下Controller:
代码在
ller;import org.springframework.beans.factory.annotation.Autowired;
import t.MessageSource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Locale;/*** @author : Sun Chuan* @date : 2019/11/24 12:32* Description:*/
@RestController
public class MessageSourceTestController {@Autowiredprivate MessageSource messageSource;@GetMapping("/")public String justTest(String lang) {//获取项目服务器所在的国家//Locale locale = Locale();Locale locale = null;switch (lang) {case "en_US":locale = Locale.US;break;case "zh_CN":locale = Locale.CHINA;break;default:locale = Locale.CHINA;}// Locale.forLanguageTag(langs)String hello = Message("hello", null, locale);return hello;}
}
我们可以通过传入不同的参数来获取到不同的值,测试结果如下:
本文发布于:2024-02-05 07:56:50,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170727827664734.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |