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代理的,那么就要看情况而定了。

posted @ 2020-10-17 17:24  戴着假发的程序员0-1  阅读(396)  评论(0编辑  收藏  举报