Hello Coder


  • 首页

  • 归档

  • 标签

  • 搜索
close

EventBus

发表于 2017-12-27

介绍

Guava提供了事件总线EventBus库,是一个基于事件的发布/订阅框架(观察者模式),通过解耦发布者和订阅者简化事件传递,可以用它在单进程中替代RabbitMQ来做事件分发。

Observer模式

Java把Observer放到了JDK里面:Observable和Observer,它简化了Observer模式的开发,至少不用再手工维护自己的Observer列表了。不过,JDK里的Observer从1.0就在那里了,直到Java 7,它都没有什么改变,就连通知的参数还是Object类型。目前很少会直接应用JDK中的Observer,Guava的EventBus也实现了Observer模式

关键点

  • 事件(Event):又可称为消息,用于订阅者和发布者之间的消息传递媒介。事件类型(EventType)一般是指一个消息对象。
  • 订阅者(Subscriber):订阅某种事件类型的对象。当有发布者发布这类事件后,EventBus 会执行订阅者的 onEvent 函数,这个函数叫事件响应函数。订阅者通过 register 接口订阅某个事件类型,unregister 接口退订。
  • 发布者(Publisher):发布某事件的对象,通过 post 接口发布事件。

流程图

eventbus img

参考

深入理解EventBus的设计思想

浏览器跨域请求

发表于 2017-12-14

在跨域情况下(源域名与目的域名不一样),浏览器可能会发起一个HTTP OPTIONS 的请求预检(preflighting)服务端是否支持CORS。如果服务端允许当前域名(源域名)CORS,则浏览器会再发起真正的请求。

跨域请求

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。只要同时满足以下两大条件,就属于简单请求。

  • 请求方法是以下三种方法之一:HEAD,GET,POST
  • HTTP的头信息不超出以下几种字段:
    • Accept
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type(只限于三个值application/x-www-form-urlencoded、 multipart/form-data、text/plain)

凡是不同时满足上面两个条件,就属于非简单请求。

简单请求

对于简单请求,浏览器直接发出CORS请求。浏览器会自动在头信息(Request Headers)中,添加一个Origin 字段,来表明本次请求来自哪个域。

  • 如果Origin不在许可范围内,会报错:
1
No 'Access-Control-Allow-Origin' header is present on the requested resource.
  • 如果Origin指定的域名在许可范围内(必须是跨域的),Response Headers中会多出几个头信息字段:
1
2
3
Access-Control-Allow-Credentials:true //值为true表示允许发送cookie
Access-Control-Allow-Methods:GET, POST, OPTIONS
Access-Control-Allow-Origin:http://localhost:8080

这几个字端要么在服务器端直接返回,要么配置在nginx中,具体实现看下文

  • withCredentials属性

CORS默认不发送cookie和http认证,如果要把Cookie发到服务器,就要指定Access-Control-Allow-Credentials:true;另外ajax中也要打开withCredentials属性

1
2
3
headers: {
withCredentials: true,
},
阅读全文 »

Spring AOP源码分析

发表于 2017-11-30

启动Spring AOP需要配置 <aop:config> 标签或者aspectj-autoproxy标签

<aop>标签解析

如果使用<aop:xxxx />标签来自动生成代理的话,入口程序是AopNamespaceHandler

1
2
3
4
5
public void init() {
// In 2.0 XSD as well as in 2.1 XSD.
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
}
  • 如果使用了<aop:config>标签,使用 ConfigBeanDefinitionParser 解析
  • 如果使用了<aop:aspectj-autoproxy>标签,使用 AspectJAutoProxyBeanDefinitionParser 解析

类结构图

这里放一张Spring AOP代理自动生成器的类图

  • <aop:config>方式使用AspectJAwareAdvisorAutoProxyCreator创建代理,`
  • <aop:aspectj-autoproxy>使用AnnotationAwareAspectJAutoProxyCreator创建代理,具体见下文

img

阅读全文 »

Spring AOP配置

发表于 2017-11-29

前文介绍了Spring AOP的一些概念,本文主要介绍Spring AOP的使用方式:基于注解和xml配置

代理原则

Spring AOP 框架对 AOP 代理类的处理原则是:如果目标对象的实现类实现了接口,Spring AOP 将会采用 JDK 动态代理来生成 AOP 代理类;如果目标对象的实现类没有实现接口,Spring AOP 将会采用 CGLIB 来生成 AOP 代理类(可以强制使用CGLIB生成代理,设置proxy-target-class=true)

注解配置

注解配置AOP(使用 AspectJ 类库实现的),大致分为三步:

  1. 使用注解@Aspect来定义一个切面,在切面中定义切入点@Pointcut,通知类型@Before,@AfterReturning,@After,@AfterThrowing,@Around
  2. 开发需要被拦截的类(普通的业务逻辑)
  3. 将切面配置到xml中,也可以使用自动扫描Bean的方式,这样切面bean交由Spring IOC容器管理。

注意:Spring只是使用了和 AspectJ 一样的注解,底层依然使用的是 Spring AOP,依然是在运行时动态生成代理

阅读全文 »

Spring AOP and AspectJ

发表于 2017-11-27

Spring AOP 和 AspectJ是Java中最流行的 AOP 框架

AOP

AOP 实现的关键就在于 AOP 框架自动创建的 AOP 代理,AOP 代理则可分为静态代理和动态代理两大类,其中静态代理是指在编译阶段修改目标类字节码,属于静态编入,不需要代理类,因此也称为编译时增强;而动态代理则在运行时借助于 JDK 动态代理、CGLIB 等在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。其中aspectj为静态代理,Spring AOP是动态代理

AOP核心概念

  • Advice:通知,是指拦截到jointpoint之后所要做的事情即特定的Jointpoint处运行的代码。
  • JoinPoint:连接点,它定义在哪里(哪些点)加入你的逻辑功能,基本每个方法的前后(两者都有也行),或抛出异常时都可以是连接点,spring只支持方法连接点
  • PointCut:切入点的集合,即一组Joinpoint,就是说一个Advice可能在多个地方织入。比如一个类里,有15个方法,那就有几十个连接点了,让切点来筛选连接点,选中那几个你想要的方法。
  • Aspect:切面,实际是通知和切入点的组合,通知说明了干什么和什么时候干(什么时候通过方法名中的before,after,around等),而切入点说明了在哪干(指定到底是哪个方法)。
  • Weaving:织入,把切面应用到目标对象来创建新的代理对象的过程。

Aspectj

ApectJ主要采用的是编译期织入,在这个期间使用AspectJ的acj编译器把aspect类编译成class字节码后,在java目标类编译时织入,即先编译aspect类再编译目标类。

img

阅读全文 »
1…678…31
David

David

Develop Notes

155 日志
37 标签
GitHub Weibo
© 2016 - 2020 David
由 Hexo 强力驱动
主题 - NexT.Pisces