Hi,大家好,我是抢老婆酸奶的小肥仔。
在我们日常开发中,Spring是必不可少的框架,我们耳熟能详的IoC,AOP都是其思想和工具。其实在日常工作中,我们比较常用的是ApplicationContext,BeanFactory等,今天我们来说说这两个类。
废话不多说,开干。
1、BeanFactory与ApplicationContext关系
1.1 ApplicationContext继承了BeanFactory,可以使用BeanFacroty中提供的方法,例如getBean
等。
1.2、BeanFactory是Spring的核心之一,ApplicationContext主要组合了BeanFactory的功能。
1.3 BeanFactory与ApplicationContext的区别?
ApplicationContext是BeanFactory的子类,BeanFactory是Spring的底层类 ApplicationContext进行了扩展,提供了国际化、统一资源文件访问方式、监听器注册bean的事件、同时加载多个配置文件。 BeanFactory:采用延迟加载方式注入bean,只有在使用某个bean时调用getBean(),才对该Bean进行加载实例化,因此不能发现一些存在问题的Spring配置问题。ApplicationContext:在容器启动时,一次性创建所有bean,因此在启动时就能检测出哪些配置问题有利于检查所有所依赖属性是否注入。在使用时,不用等待bean创建。 由于ApplicationContext一次加载所有bean,可能导致占用内存空间不足,程序启动慢 BeanFactory:通常以编程的方式创建,ApplicationContext:以声明的方式创建 BeanFactory与ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor使用,BeanFactory使用需要手动注册,ApplicationContext则自动注入
2、BeanFactory接口
该接口主要提供了containsBean
,getAliases
,getBean
等方法
DefaultListableBeanFactory是BeanFactory的一个实现类,其不仅实现了BeanFactory的方法,也实现了其他接口或方法。
SingletonBeanRegistry
:单例bean的注册
SimpleAliasRegistry
:简单的别名注册
BeanDefinitionRegistry
:bean的注册
Serializable
:序列化
3、ApplicationContext功能
ApplicationContext继承了BeanFactory,实现了其功能外,还实现了其他功能。
3.1 MessageSource(国际化)
3.1.1 在resources
目录下创建messages.propertes
、 messages_en.properties
、 messages_ja.properties
、 messages_zh.properties
配置文件,并分别编写语言对应键值对。如图:
3.1.2 注入ApplicationContext
@Resource
private ApplicationContext applicationContext;
3.1.3 调用getMessage()实现转换
applicationContext.getMessage("hi", null, Locale.CHINA)
3.1.4 输出结果
3.2 ResourcePatternResolver(统一资源文件访问)
ResourcePatternResolver
即对项目中的资源文件进行访问,拿到我们想要的配置信息。
注:如需对jar包中的资源进行获取时需在classpath前添加*,即classpath*:
//获取当前项目目录下的message开头的资源
Resource[] resources = context.getResources("classpath:message*.properties");
for (Resource resource : resources) {
System.out.println("获取资源:"+resource);
}
//获取当前项目目录下的META-INF资源,包括jar中的数据
Resource[] facResources = context.getResources("classpath*:META-INF/spring.factories");
for (Resource resource : facResources) {
System.out.println("获取fac资源:"+resource);
}
执行结果:
3.3 EnvironmentCapable(环境变量)
EnvironmentCapable:对系统或者电脑的配置的环境变量进行获取
获取配置文件信息时相当于@Value
String java_home = context.getEnvironment().getProperty("java_home");
String port = context.getEnvironment().getProperty("server.port");
System.out.println("java_home:"+java_home);
System.out.println("port:"+port);
执行结果:
3.4 ApplicationEventPublisher(事件监听)
提供监听作用,实现代码的解耦。
3.4.1 用户事件注册
即通过继承ApplicationEvent将事件进行注册
@Getter
public class SelfDefineEvent extends ApplicationEvent {
private AdminUser user;
public SelfDefineEvent(Object source,AdminUser user) {
super(source);
this.user = user;
}
}
3.4.2 事件发布
即通过@Autowired注入ApplicationEventPublisher
或者ApplicationContext
调用publishEvent()
对事件进行发布。
@Resource
private ApplicationContext applicationContext;
@Autowired
private ApplicationEventPublisher eventPublisher;
@Override
public ResultUtil selfDefineUser() {
AdminUser adminUser = new AdminUser("queena","11111111");
SelfDefineEvent defineEvent = new SelfDefineEvent(this, adminUser);
//applicationContext.publishEvent(defineEvent);
eventPublisher.publishEvent(defineEvent);
return ResultUtil.success();
}
3.4.3 @EventListener接收事件或实现接口ApplicationListener
1、注解@ApplicationListener
@Component
@Slf4j
public class UseAnnotatedListener {
@EventListener
public void getSelfDefine(SelfDefineEvent event){
log.info("监听事件:{}",event.getUser());
}
}
执行结果:
2、实现接口
@Component
@Slf4j
public class SelfDefineEventListener implements ApplicationListener {
@Override
public void onApplicationEvent(SelfDefineEvent event) {
AdminUser user = event.getUser();
log.info(String.format("用户名:%s,密码:%s",user.getUserName(),user.getPassword()));
}
}
执行结果:
在日常开发中,很多时候为了实现业务解耦,则可以采用监听器这种方式来实现。
好了,今天的分享就到这了,希望我的分享对大家有所帮助。