笔记9 AOP练习3(通过注解引入新功能 )
Posted 飘来荡去
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了笔记9 AOP练习3(通过注解引入新功能 )相关的知识,希望对你有一定的参考价值。
切面可以为Spring bean添加新方法。 在Spring中,切面只是实现了它们所包装bean相同接口的 代理。如果除了实现这些接口,代理也能暴露新接口的话,会怎么样 呢?那样的话,切面所通知的bean看起来像是实现了新的接口,即便 底层实现类并没有实现这些接口也无所谓。
使用Spring AOP,我们可以为bean引入新的方法。 代理拦截调用并委托给实现该方法的其他对象
需要注意的是,当引入接口的方法被调用时,代理会把此调用委 托给实现了新接口的某个其他对象。实际上,一个bean的实现被拆分 到了多个类中。
场景描述:
在一场音乐会中,添加川剧变脸的环节,但在原来的古典音乐表演类(Classcial.java)中没有这个方法,所以需要为这个表演类再新加一个方法。
1.创建一个新的接口Encoreable.java
1 package concert2; 2 3 public interface Encoreable { 4 void performEncore(); 5 }
2.实现这个接口DefaultEncoreable.java
1 package concert2; 2 3 public class DefaultEncoreable implements Encoreable { 4 5 @Override 6 public void performEncore() { 7 // TODO Auto-generated method stub 8 System.out.println("川剧变脸"); 9 } 10 11 }
3.创建一个用于注入新方法的切面EncoreableIntroducer.java
1 package concert2; 2 3 import org.aspectj.lang.annotation.Aspect; 4 import org.aspectj.lang.annotation.DeclareParents; 5 import org.springframework.stereotype.Component; 6 7 @Aspect 8 @Component 9 public class EncoreableIntroducer { 10 @DeclareParents(value = "concert2.Performance+", defaultImpl = DefaultEncoreable.class) 11 public static Encoreable encoreable; 12 }
EncoreableIntroducer是一个切面,同时声明它是一个bean。但是,它与我们 之前所创建的切面不同,它并没有提供前置、后置或环绕通知,而是 通过@DeclareParents注解,将Encoreable接口引入 到Performance bean中。 @DeclareParents注解由三部分组成:
- value属性指定了哪种类型的bean要引入该接口。在本例中,也 就是所有实现Performance的类型。(标记符后面的加号表示 是Performance的所有子类型,而不是Performance本 身。)
- defaultImpl属性指定了为引入功能提供实现的类。在这里, 我们指定的是DefaultEncoreable提供实现。
- @DeclareParents注解所标注的静态属性指明了要引入了接 口。在这里,我们所引入的是Encoreable接口。
而且在将EncoreableIntroducer声明为一个bean后,Encoreable也就成为了一个bean。
3.采用java装配bean ConcertConfig.java
1 package concert2; 2 3 import org.springframework.context.annotation.ComponentScan; 4 import org.springframework.context.annotation.Configuration; 5 import org.springframework.context.annotation.EnableAspectJAutoProxy; 6 7 @Configuration 8 @EnableAspectJAutoProxy // 启用AspectJ自动代理 9 @ComponentScan 10 public class ConcertConfig { 11 12 }
4.测试
在此做了对比,因为Encoreable已经声明为bean,所以也可以直接加载,然后调用其方法。其次,因为Encoreable的方法已经添加到Performance中,所以也可以通过Performance的对象进行调用,但需要注意的是,在调用新加入的方法时要进行“伪装”,即将Performance的对象强制转换为Encoreable,然后再调用新加入的方法,以逃过编译器的检查。如果不进行引入的话,强行改变Performance对象的类型,然后调用“新方法”,则会报错。
1 package concert2; 2 3 import org.junit.Test; 4 import org.junit.runner.RunWith; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.test.context.ContextConfiguration; 7 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 8 9 @RunWith(SpringJUnit4ClassRunner.class) 10 @ContextConfiguration(classes = concert.ConcertConfig.class) 11 public class ConcertTest { 12 @Autowired 13 public Performance p; 14 @Autowired 15 public Encoreable en; 16 @Test 17 public void test() { 18 p.perform(); 19 System.out.println("-----------------------------"); 20 System.out.println("自己创建对象调用"); 21 en.performEncore(); 22 System.out.println("-----------------------------"); 23 System.out.println("通过Performance对象调用“新方法”"); 24 Encoreable e = (Encoreable) p; 25 e.performEncore(); 26 } 27 }
5.结果
省略的部分请参照笔记7
以上是关于笔记9 AOP练习3(通过注解引入新功能 )的主要内容,如果未能解决你的问题,请参考以下文章
Spring框架学习笔记 --- [在spring中初步上手实现AOP,以及对事务的初步配置使用]