Springboot容器接口
目标:
- BeanFactory能做那些事
- ApplicationContext有哪些扩展功能
- 事件解耦
1. beanFactory能干什么
- 作为spring容器的顶级接口
- 含有抽象getBean方法
- DefaultListableBeanFactory为其实现类,并为DefaultSingletonBeanRegistry的子类含有singletonObjects存放bean
public static void main(String[] args) {
/*可配置的ApplicationContext*/
ConfigurableApplicationContext context
= SpringApplication.run(Day01Application.class, args);
/*反射获取bean*/
Field field = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
field.setAccessible(true);
ConfigurableListableBeanFactory factory = context.getBeanFactory();
Map<String,Object> map = (Map<String, Object>) field.get(factory);
*//*entrySet将map的元素放入set中*//*
map.entrySet().stream()
.filter(e->e.getKey().startsWith("component"))
.forEach(e-> System.out.println(e.getKey()+":"+e.getValue()));
}
2. ApplicationContext扩展功能
实现的接口:
2.1 MessageSource处理国际化问题
- 创建资源目录及文件
- 进行语言转换
System.out.println(context.getMessage("hi", null, Locale.CHINA));
System.out.println(context.getMessage("hi", null, Locale.ENGLISH));
System.out.println(context.getMessage("hi", null, Locale.JAPANESE));
2.2 ResourcePatternResolver处理资源匹配
- 获取jar包里的spring.factories文件
Resource[] resources = context.getResources("classpath*:META-INF/spring.factories");
for (Resource resource : resources) {
System.out.println(resource);
}
2.3 EnvironmentCapable 获取系统和yml、properties中的变量
ConfigurableEnvironment environment = context.getEnvironment();
String java_home = environment.getProperty("JAVA_HOME");
System.out.println(java_home);
3. ApplicationEventPublisher 发布和监听
- 定制事件
public class UserRegisteredEvent extends ApplicationEvent {
public UserRegisteredEvent(Object source) {
super(source);
}
}
- 发布事件
@Component
@Slf4j
public class Component1 {
/*消息发布*/
public void register( @Autowired ApplicationEventPublisher context){
log.warn("用户注册!!!");
context.publishEvent(new UserRegisteredEvent(context));
}
}
- 监听和接收事件
@Component
@Slf4j
public class Component2 {
@EventListener
/*事件监听*/
public void SendMessage(UserRegisteredEvent event) {
log.warn("{}", event);
log.warn("发送短信");
}
}
…感觉有点鸡肋
4. 练习 AOP实现3的功能
@Aspect
@Component
@Slf4j
public class SendMessage {
@Pointcut("@annotation(com.example.day01.aop.Sendxx)")
public void send(){}
@Around("send()")
public Object sendEmail(ProceedingJoinPoint point) throws Throwable {
Object proceed = point.proceed(point.getArgs());
log.warn("发送短信!!!");
return proceed;
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Sendxx {
}
@Component
@Slf4j
public class UserRegister {
@Sendxx
public void register(){
log.warn("用户注册!!");
}
}
context.getBean(UserRegister.class).register();