• Spring学习笔记(三) AOP_annotation,AOP_XML


    在学习课程以前,听说AOP有种很神秘的感觉,好像很好深的技术。其实原理很简单,使用动态代理的方式给程序增加逻辑。与此相似的有struts2中的filter拦截器。

    再讲AOP之前先把需求说一下: 同Spring学习笔记(一)IoC中的需求一样,只不过要在save()方法前后增加日志log的记录。

    不使用AOP的方式可以有两种实现思路:

    1—>使用继承的的方式,把有save方法的类继承,然后在增加log逻辑

    2—>使用组合的方式,即增加一个记录逻辑的类,分别有在save()方法前save()方法后记录日志的功能,然后把这两个类组合到一起

    虽然上面两种方式都能解决我们的需求,但是一个问题来了:如果有500个更甚至1000各类中的方法需要增加逻辑,使用继承的方法和组合的方法的弊端就出来了。一方面会增加海量的代码量。另一方面,会使整个程序的可读性变差。程序员在写程序的时候不能专注于业务逻辑,还要专注于维护逻辑,增加程序员的逻辑压力,从而用于调试的时间会增多。

    从而,出现了AOP,来解决这类问题。Spring中的AOP实现原理使用的是JavaJDK中的动态代理。

    AOP_annotation

    AOP_annotation环境搭建

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4.        xmlns:aop="http://www.springframework.org/schema/aop"
    5.         xsi:schemaLocation="http://www.springframework.org/schema/beans
    6.            http://www.springframework.org/schema/aop
    7.            http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    8.     <aop:aspectj-autoproxy />
    9. </beans>

    增加AOP的xml命名空间以及xsd路径设置。最重要的是增加<aop:aspect-autoproxy>

    Aspectj是专门用来实现动态代理的类库,spring中的AOP使用的是aspectj.jar实现的。需要在库中增加aspectj的类库。

    @Aspect,@Before

    @Aspect:即标注这个类为切面类,是增加的逻辑的那个类。放在我们的需求里面,log记录方法应写在被@Aspect标注的类

    @Before:切入点的逻辑,即是在增加save()方法前面执行

    Execution…:切入点语法

    1. @Aspect
    2. @Component
    3. public class LogInterceptor {
    4.   @Before("execution(* com.xxxx.dao.impl.UserDAOImpl.save(com.xxxx.model.User))")
    5.    public void before() {
    6.       System.out.println("method before");
    7.    }
    8. }

    其中@Before口号中的execution()是注册那个保重的那个类中的那个方法加入切入逻辑。

    @PointCut

    1. @Aspect
    2. @Component
    3. public class LogInterceptor {
    4.    @Pointcut("execution(public * com.xxxx.service..*.add(..))")
    5.    public void myMethod(){};
    6. }

    @PointCut:切入点集合。即对com.xxx.service包中的类中任何返回值的add()方法(add()方法的参数任意)增加切入逻辑    

    这种给相关方法加入切入逻辑的动作又叫作织入(Weave),切入点语法为execution的为aspectj的织入语法。Spring AOP也有自己的语法,到时候查阅参考文档吧!

    @AfterReturning,@AfterThrowing,@After(finally)

    这些方法的使用跟@Before类似

    @Around

    1. @Aspect
    2. @Component
    3. public class LogInterceptor {
    4.    @Pointcut("execution(public * com.bjsxt.service..*.add(..))")
    5.    public void myMethod(){};
    6.    @Around("myMethod()")
    7.    public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
    8.       System.out.println("method around start");
    9.       pjp.proceed();
    10.       System.out.println("method around end");
    11.    }
    12. }

    其中有两个知识点

        1à这一点在刚才说@PointCut是没有说明,就是呗@PointCut标记的方法名字myMethod为@PointCut所标记的那些切入点方法集合的表示符号。举个例子,

    int myMethod=@PointCut

        2à@around要使用pjp.proceed()执行切入点save()方法

    AOP_XML

    1. <bean id="logInterceptor" class="com.bjsxt.aop.LogInterceptor" ></bean>
    2. <aop:config>
    3.     <aop:aspect id="logAspect" ref="logInterceptor" >
    4.         <aop:pointcut id="myMethod" expression="execution(public void com.bjsxt.dao.impl.UserDAOImpl.save(com.bjsxt.model.User))"></aop:pointcut>
    5.         <aop:before method="before" pointcut-ref="myMethod"></aop:before>
    6.       <aop:after-returning method="myafter" pointcut="execution(public void com.bjsxt.dao.impl.UserDAOImpl.save(com.bjsxt.model.User))">
    7.     </aop:aspect>
    8. </aop:config>

    上述代码写了AOP中XML方式书写的格式,其中pointcut的三种写法都在上面4,5,6行中。

  • 相关阅读:
    Nginx 启动错误 Failed to read PID from /run/nginx.pid
    CentOS7 下 nginx 无法加载 Django 静态文件的问题
    SSD + 机械硬盘装 CentOS 分区的问题
    CentOS7 单机维护模式
    编译安装 redis 6.2.1
    谷歌师兄刷题笔记
    我用 DCL 写出了单例模式,结果阿里面试官不满意!
    红黑树杀人事件始末
    头条二面:详述一条 SQL 的执行流程
    jvisual远程 springBoot项目
  • 原文地址:https://www.cnblogs.com/wenlonghor/p/3295863.html
Copyright © 2020-2023  润新知