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