目录
引入
解析
示例
-
引入
- Java不是动态语言;一旦类编译完成了,我们就很难再为该类添加新的功能了
- 切面能够为现有的方法增加额外的功能,为什么不能为一个对象增加新的方法呢?
- 实际上,利用被称为引入的AOP概念,切面可以为Spring bean添加新方法
-
解析
- 在Spring中,切面只是实现了它们所包装bean相同接口的代理
- 如果除了实现这些接口,代理也能暴露新接口的话,会怎么样呢?
- 那样的话,切面所通知的bean看起来像是实现了新的接口,即便底层实现类并没有实现这些接口也无所谓
- 如图展示了它们是如何工作的:
- 使用Spring AOP,我们可以为bean引入新的方法
- 代理拦截调用并委托给实现该方法的其他对象
- 需要注意的是,当引入接口的方法被调用时,代理会把此调用委托给实现了新接口的某个其他对象
- 实际上,一个bean的实现被拆分到了多个类中
- @DeclareParents 注解,它可以在代理目标类上增加新的行为(新增新的方法)
- @DeclareParents 注解由三部分组成:
- value属性指定了哪种类型的bean要引入该接口(标记符后面的加号表示是接口的所有子类型,而不是接口本身)
- defaultImpl属性指定了为引入功能提供实现的类
- @DeclareParents 注解所标注的静态属性指明了要引入了接口
-
示例
- 被代理的bean:
- 代理增强类:
- 代理类配置:
- 启用AspectJ自动代理:
- 测试类:
- 结果为:
- 有的人会问为什么不直接在原始的接口中新加方法
- 当然这种也是可以的,但是这样做有个问题,加入原始接口下面有好多实现类,则需要对所有的实现类进行修改
- 这样做功能能够完成,但是从设计角度来看并不是最好的做法
- 况且有的时候根本没有机会修改所有的实现类,比如假如引用的原始类是第三方提供的并且没有源码
- 这种情况就没有办法通过直接扩展原始类来解决问题