Spring—切点表达式


摘要: Spring中的AspectJ切点表达式函数 切点表达式函数就像我们的GPS导航软件。通过切点表达式函数,再配合通配符和逻辑运算符的灵活运用,我们能很好定位到我们需要织入增强的连接点上。经过上面的铺垫,下面来看看Springz中支持的切点表
Spring中的AspectJ切点表达式函数
切点表达式函数就像我们的GPS导航软件。通过切点表达式函数,再配合通配符和逻辑运算符的灵活运用,我们能很好定位到我们需要织入增强的连接点上。经过上面的铺垫,下面来看看Springz中支持的切点表达式函数。
1. 方法切点函数
函数
入参
说明
示例
execution()
方法匹配字符串
满足某一匹配模式的的所有目标类方法连接点
execution(* com.yc.service.*.*(..))在配置service层的事务管理时常用,定位于任意返回类型(第一个”*”) 在com.yc.service包下的所有类(第二个”*”)下的所有方法(第三个”*”),且这个方法的入参为任意类型、数量(体现在 “(..)“)
@annotation()
方法注解类名
标注了特定注解的目标方法连接点上
@anntation(com.yc.controller.needRecord),定位于controller层中任何添加@needRecord的方法,这可以方便地对控制层中某些方法被调用(如某人某时间登陆、进入后台管理界面)添加日志记录。
1. execution详解
execution的语法表达式如下:execution(<修饰符> <返回类型> <类路径> <方法名>(<参数列表>) <异常模式> ) 
其中,修饰符和异常是可选的,如果不加类路径,则默认对所有的类生效。它常用实例如下:
1. 通过方法签名、返回值定义切点:
- `execution(public * *Service(..))`:定位于所有类下返回值任意、方法入参类型、数量任意,public类型的方法
- `execution(public String *Service(..))`:定位于所有类下返回值为String、方法入参类型、数量任意,public类型的方法
2. 通过类包定义切点:
- `execution(* com.yc.controller.BaseController+.*(..))`:匹配任意返回类型,对应包下BaseController类及其子类等任意方法。
- `execution(* com.*.(..))`:匹配任意返回类型,com包下所有类的所有方法
- `execution(* com..*.(..))`:匹配任意返回类型,com包、子包下所有类的所有方法
注意.表示该包下所有类,..则涵括其子包。
3. 通过方法入参定义切点
- 这里“\*”表示任意类型的一个参数,“..”表示任意类型任意数量的参数
- `execution(* speak(Integer,*))`:匹配任意返回类型,所有类中只有两个入参,第一个入参为Integer,第二个入参任意的方法
- `execution(* speak(..,Integer,..))`:匹配任意返回类型,所有类中至少有一个Integer入参,但位置任意的方法。
2. annotation详解
此注解用于定位标注了某个注解的目标切点。下面我们来看一个模拟用户登录成功后日志记录用户名、时间和调用方法的示例,
1. 自定义注解
@Retention(RetentionPolicy.CLASS)//生命注释保留时长,这里无需反射使用,使用CLASS级别
@Target(ElementType.METHOD)//生命可以使用此注解的元素级别类型(如类、方法变量等)
public @interface NeedRecord {
}
关于自定义注解的更多属性与说明,可查看我的另一篇文章 http://blog.csdn.net/qwe6112071/article/details/50949663
2. 定义切面(配置增强和定位切点)
@Aspect//将当前类标注成一个切面。
public class Annotation_aspect {
    @AfterReturning("@annotation(test.aop2.NeedRecord)")//这里指向注解类
    public void Record(JoinPoint joinPoint){//切点入参。
        System.out.println("日志记录:用户" +joinPoint.getArgs()[0] + "在" + new SimpleDateFormat("yyyy-MM-dd hh:mm;ss").format(new Date()) + "调用了"+ joinPoint.getSignature()+"方法" );
    }
}
3. 定义目标对象
@NeedRecord
public void login(String name){
    System.out.println("I'm "+name+" ,I'm logining");
}
4. 配置IOC容器
<aop:aspectj-autoproxy />   <!-- 使@AspectJ注解生效 -->
<bean class="test.aop2.Annotation_aspect" /><!-- 注册切面,使AOP自动识别并进行AOP方面的配置 -->
<bean id="userController" class="test.aop2.UserController" /><!-- 注册目标对象 -->
这里需注意: 
1. 和 标注在目标对象Annotation_aspect的注解@Aspect缺一不可,否则调用login方法时,Record方法不会被调用 
2. 必须在IOC容器中注册切面和目标对象,以便在下面测试中通过
5. 测试
public static void main(String args[]){
        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:test/aop2/aop.xml");
        UserController userController = (UserController) ac.getBean("userController");
        userController.login("zenghao");
    }
调用测试方法后,会打印信息: 
I’m zenghao ,I’m logining 
DEBUG: org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean ‘test.aop2.Annotation_aspect#0’//log4j的日志记录打印 
日志记录:用户zenghao在2016-03-21 08:27;48调用了void test.aop2.UserController.login(String)方法
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值