3.10@Pointcut的表达式-this
戴着假发的程序员出品 抖音ID:戴着假发的程序员 欢迎关注
[查看视频教程]
限制与连接点的匹配,其中 bean reference(Spring AOP 代理)是给定的具体类型。
就是说在this中我们配置的都是具体的类型,也就是全限定类名。注意This中不支持通配符。
官方给出的案例:
this(com.st.dk.demo7.service.BookService)
这时BookService中的所有方法就会被拦截。
案例:
我们修改前面案例中的配置:
1 /** 2 * @author 戴着假发的程序员 3 * 4 * @description 5 */ 6 @Component //将当前bean交给spring管理 7 @Aspect //定义为一个AspectBean 8 public class DkAspect { 9 @Pointcut("within(com.st.dk.demo7.service.BookService)") 10 private void pointCut1(){} 11 //定义一个前置通知 12 @Before("pointCut1()") 13 private static void befor(){ 14 System.out.println("---前置通知---"); 15 } 16 }
测试:
1 @Test 2 public void testAopPointCutThis(){ 3 ApplicationContext ac = 4 new AnnotationConfigApplicationContext(Appconfig.class); 5 IBookService bean = ac.getBean(IBookService.class); 6 bean.saveBook("论一个假发程序员的修养"); 7 }
结果:
当然this中也可以配置一个接口,那么这个接口中的所有方法都会增强:
案例:
我们添加一个IBookService接口:
1 /** 2 * @author 戴着假发的程序员 3 * 4 * @description 5 */ 6 public interface IBookService { 7 public void saveBook(String title); 8 }
让我们的BookService实现这个接口,并且添加一个自己额外的方法:
1 /** 2 * @author 戴着假发的程序员 3 * 4 * @description 5 */ 6 @Component 7 public class BookService implements IBookService{ 8 @Override 9 public void saveBook(String title){ 10 System.out.println("保存图书:"+title); 11 } 12 public void getBook(){ 13 System.out.println("获取图书:程序员的修养"); 14 } 15 }
这里要特别注意一个问题:
我们的例子中,IBookService中只有一个savebook()的方法,实现类中增加了getBook()方法,如果我们使用的代理方式是JKD代理,则代理对象是按照接口实现的,也就是代理对象中根本就不存在getBook()方法,当然也不会有拦截作用。
但是如果使用CGLib代理方式,那么子类扩展的方法getBook()也会被代理,并且被拦截。
我们修改配置:
1 /** 2 * @author 戴着假发的程序员 3 * 4 * @description 5 */ 6 @Component //将当前bean交给spring管理 7 @Aspect //定义为一个AspectBean 8 public class DkAspect { 9 //使用this指定全限定类名 10 @Pointcut("this(com.st.dk.demo7.service.IBookService)") 11 private void pointCut1(){} 12 //定义一个前置通知 13 @Before("pointCut1()") 14 private static void befor(){ 15 System.out.println("---前置通知---"); 16 } 17 }
测试:
1 @Test 2 public void testAopPointCutThis(){ 3 ApplicationContext ac = 4 new AnnotationConfigApplicationContext(Appconfig.class); 5 //注意这里要获取接口类型 6 IBookService bean = ac.getBean(IBookService.class); 7 bean.saveBook("论一个假发程序员的修养"); 8 }
结果
我们可以修改主配置类,强制使用CGLib代理:
1 /** 2 * @author 戴着假发的程序员 3 * 4 * @description 5 */ 6 @Configuration 7 @ComponentScan("com.st.dk.demo7") 8 //这里通过proxyTargetClass = true 强制使用CGLib代理 9 @EnableAspectJAutoProxy(proxyTargetClass = true) //开启@AspectJ 支持 10 public class Appconfig { 11 }
继续修改测试:
1 @Test 2 public void testAopPointCutThis(){ 3 ApplicationContext ac = 4 new AnnotationConfigApplicationContext(Appconfig.class); 5 IBookService bean = ac.getBean(IBookService.class); 6 bean.saveBook("论一个假发程序员的修养"); 7 ((BookService)bean).getBook(); 8 }
结果:
我们会发现两个方法都被增强了。
当然了,this中不光可以指定具体类,接口。 也可以指定一个父类,那么这个父类的所有子孙类的方法都会被拦截,当然如果是使用JDK代理的,那么就要看情况而定了。
我是戴着假发的程序员,分享技术,分享经验,如果要转载,请注明:出自戴着假发的程序员