统一资源加载策略
提供了一套统一的资源抽象接口,以Resource接口为顶层接口。
实现类如下
ByteArrayResource 将字节数组提供的资源作为资源封装,如果通过InputStream形式方位该类型的数据,会返回该类型的数组
ClassPathResource 从Java程序的ClassPath加载资源封装,使用类加载器或指定类以进行加载
FileSystemResource
UrlResource
InputStreamResource 使用较少,以ByteArrayResource实现代之
查找和定位这些资源的抽象是ResourceLoader接口
实现类
DefaultResourceLoader 首先检查资源路径是否以ClassPath:前缀开头,是则构造ClassPathResource;不是则尝试通过URL定位,依然不是则使用getResourceByPath定位,构造ClassPathResouce类型,并抛出异常
FileSystemResourceLoader 对getResourceByPath的返回值是FileSystemResource
ResourcePatternResolver 支持批量查找的ResourceLoader
ApplicationContext使用ResourceLoader
```
ResourceLoader resourceLoader = new ClassPathXmlApplicationContext("xml file path")
Resource fileResource = resourceLoader.getResource("F:/spring/pom.xml");
```
国际化信息支持
容器内事件发布
1.自定义事件发布
Spring使用的事件继承自JavaSE,EventObject类型和EventListener接口,实现自定义事件代码如下
实现自定义事件类型
```
public class MethodExecutionEvent extends EventObject{
private String methodName;
public MethodExecutionEvent(Object source){
super(source);
}
public MethodExecutionEvent(Object source, String methodName){
super(source);
this.methodName = methodName;
}
...
}
```
实现自定义事件类对应的事件监听器接口
```
public interface MethodExecutionEventListener extends EventListener{
/**
* 处理方法开始执行的时候发布的MethodExecutionEvent事件
*/
void onMethodBegin(MethodExecutionEvent evt);
/**
* 处理方法结束执行的时候发布的MethodExecutionEvent事件
*/
void onMethodEnd(MethodExecutionEvent evt);
}
```
自定义的事件监听器接口的实现类
```
public class SimpleMethoExecutionEventListener implements MehodExecutionEventListener{
...
}
```
组合事件类和监听器,发布事件
```
public class MethodExeuctionEventPublisher{
private List<MethodExecutionEventListener> listeners = new ArrayList<>();
public void methodToMonitor(){
methodExecutionEvent event2Publish = new MethodExecutionEvent(this, "methodToMonitor");
//监听器接口的调用
publishEvent(Status.BEGIN, event2Publish);
...
publishEvent(Status.END, event2Publish);
}
public void publishEvent(){
...
}
public void addMethodExeuctionEventListener(MehodExecutionEventListener listener){
listeners.add(listener);
}
public static void main(String[] args){
MehodExecutionEventPublisher eventPublisher = new MehodExecutionEventPubliser();
eventPublisher.addMehodExecutionEventListener(new SimpleMehodExecutionEventListener());
eventPublisherv.methodToMonitor();
}
}
```
ApplicationContext允许事件以ApplicationEvent发布,容器内注册的ApplicationListener类型的bean定义会被容器识别,监听容器内发布的ApplicationEvent事件。ApplicationContext就是publisher的身份。
默认实现 ContextClosedEvent ContextRefreshedEvent RequestHandledEvent
Spring内事件发布
事件需要ApplicationEventPublisher的事件发布支持,因此需要注入实例,使用ApplicationEventPublisherAware或ApplicationContextAware接口即可(利用bean初始化过程以自动的注入)
由于Spring提供了监听器,可以把原本的监听器接口直接作为实现类
```
public class MethodExeuctionEventListener implements ApplicationListener{
public void onApplicationEvent(ApplicationEveent evt){
if(evt instanceof MethodExeuctionEventEvent){
...
}
}
}
```
对发布器的改造,由于发布者也是Spring容器
```
public class MethodExeuctionEventPublisher implements ApplicationEventPublisherAware{
private ApplicationEventPublisher eventPublisher;
public void methodToMethod(){
...
}
public void setApplicationEventPubliser(ApplicationEventPubliser appCtx){
...
}
}
```
注入相关实例
```
<bean id="methodExecListener" class="...MethodExeuctionEventListener"/>
<bean id="evtPublisher" class="...MethodExeuctionEventPublisher"/>
```