美文网首页
Spring AOP用法

Spring AOP用法

作者: sunpy | 来源:发表于2018-08-22 20:44 被阅读25次

介绍

在开发中我们经常使用oop这种纵向结构来开发,但是却会出现一些横切的功能。譬如,日志记录的功能,我们需要在每个方法执行的详细信息通过日志记录,但是我们为每个方法去写日志,明显不合理。再如异常处理功能,我们需要在每个方法执行抛出的异常都专门处理都不合理。这样就需要AOP面向切面开发来处理横切问题。

AOP术语

  1. 通知:
    通知主要是定义切面是什么以及何时使用。
    Before:在接合点之前执行通知。
    AfterReturning:在接合点执行完成之后执行通知。
    AfterThrowing:如果从接合点抛出了任何异常,都执行通知。
    After:接合点执行完成之后,无论是否抛出了异常,都执行通知。
    Around:在接合点周围执行通知,意思就是可能在接合点之前执行,也可能在接合点之后执行。
  2. 连接点:
    意思就是代码中的点,在这个点上开始玩切面。效果肯定是向应用程序中插入额外的逻辑。
  3. 切点:
    用来选择需要执行一个或者多个连接点的表达式。
  4. 切面:
    切面就是切点和通知的结合。
  5. 织入:
    将方面与目标对象结合在一起的过程。
  6. 引入:
    动态地为已经存在的类添加属性和方法。

XML方式实现AOP

配置文件:

    <context:component-scan base-package="cn.spy"></context:component-scan>
    <context:annotation-config></context:annotation-config>
    <aop:config>
        <aop:pointcut expression="execution(* cn.spy.service.impl.MyServiceImpl.*(..))" id="pc"/>
        <aop:aspect ref="myAop">
            <aop:before method="beforeExecute" pointcut-ref="pc"/>
            <aop:after method="afterExecute" pointcut-ref="pc"/>
        </aop:aspect>
    </aop:config>

强制设置使用cglib代理:<aop:config proxy-target-class="true">

业务类和接口

public interface MyService {
    public void serviceMed();
}

@Component("myService")
public class MyServiceImpl extends BaseLog implements MyService{

    @Override
    public void serviceMed() {
        System.out.println("业务逻辑方法");
    }
}

切面类:

@Component("myAop")
public class MyAop extends BaseLog {
    
    public void beforeExecute() {
        System.out.println("before execute");
    }
    
    public void afterExecute() {
        System.out.println("after execute");
    }
}

测试类:

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        MyService myService = (MyService) context.getBean("myService");
        myService.serviceMed();
    }

结果:


1.jpg

注解方式实现AOP

配置文件:

    <context:component-scan base-package="cn.spy"></context:component-scan>
    <context:annotation-config></context:annotation-config> 
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

切面类:

@Component("myAop")
@Aspect
public class MyAop extends BaseLog {
    
    @Pointcut("execution(* cn.spy.service.impl.MyServiceImpl.*(..))")
    public void cutMethod() {
        
    }
    
    @Before("cutMethod()")
    public void beforeExecute() {
        System.out.println("before execute");
    }
    
    @After("cutMethod()")
    public void afterExecute() {
        System.out.println("after execute");
    }
}

强制使用cglib代理:@EnableAspectJAutoProxy(proxyTargetClass=true)


切点表达式

  1. 表达式语法:
execution(<scope> <return-type><fully-qualified-class-name>.*(parameters))
  1. 例子:
    execution(* cn.spy.service.impl.MyServiceImpl.(..))
    解释:匹配cn.spy.service.impl.MyServiceImpl类下的所有方法
    execution(public void cn.spy.service.impl.MyServiceImpl.
    (..))
    解释:匹配cn.spy.service.impl.MyServiceImpl类下的public void xx();方法。
    execution(public void cn.spy.service.impl.MyServiceImpl.*(String,..))
    解释:匹配cn.spy.service.impl.MyServiceImpl类下第一个参数为String类型,无返回值的所有公共方法。
  2. 通配符:
    ..该通配符匹配方法定义中的任何数量的参数。(也可以匹配任意数量的包)
    +该通配符匹配给定类的任何子类。
    *该通配符匹配任意数量的字符。

相关文章

网友评论

      本文标题:Spring AOP用法

      本文链接:https://www.haomeiwen.com/subject/exysiftx.html