• AspectJ框架基于注解的AOP实现


    AspectJ的AOP实现:有两种方式,一种是基于XML配置文件,一种是基于注解的,由于注解更为常用,这里

                                  这里只针对注解来学习。

    --------------------------------------------------------------------------------------

     1 package com.sjl.aspectj.annotation;
     2 
     3 import org.aspectj.lang.JoinPoint;
     4 import org.aspectj.lang.ProceedingJoinPoint;
     5 import org.aspectj.lang.annotation.*;
     6 import org.springframework.stereotype.Component;
     7 
     8 /**
     9  * 切面类,在此类中编写通知
    10  * */
    11 @Aspect
    12 @Component //这个注解的作用是实例化对象,相当于在配置文件中<bean id="" class="">
    //由于是个java类,所以要实例化,相当于在Spring容器中声明这个文件是java类,
    //并且是一个切面类
    13 public class MyAspect { 14 //定义切入点表达式 15 @Pointcut("execution(* com.sjl.jdk.*.*(..))") 16 //用一个返回值为void、方法体为空的方法来命名切入点 17 private void myPoint(){ } 18 19 // 前置通知 20 @Before("myPoint()") 21 public void myBefore(JoinPoint joinPoint) { 22 System.out.print("前置通知 :模拟执行权限检查...,"); 23 System.out.print("目标类是:"+joinPoint.getTarget().getClass() ); 24 System.out.println(",被织入增强处理的目标方法为:" 25 +joinPoint.getSignature().getName()); 26 } 27 28 // 后置通知 29 @AfterReturning("myPoint()") 30 public void myAfterReturning(JoinPoint joinPoint) { 31 System.out.print("后置通知:模拟记录日志...," ); 32 System.out.println("被织入增强处理的目标方法为:" 33 + joinPoint.getSignature().getName()); 34 } 35 36 /** 37 * 环绕通知 38 * ProceedingJoinPoint 是JoinPoint子接口,表示可以执行目标方法 39 * 1.必须是Object类型的返回值 40 * 2.必须接收一个参数,类型为ProceedingJoinPoint 41 * 3.必须throws Throwable 42 */ 43 @Around("myPoint()") 44 public Object myAround(ProceedingJoinPoint proceedingJoinPoint) 45 throws Throwable { 46 // 开始 47 System.out.println("环绕开始:执行目标方法之前,模拟开启事务..."); 48 // 执行当前目标方法 49 Object obj = proceedingJoinPoint.proceed(); 50 // 结束 51 System.out.println("环绕结束:执行目标方法之后,模拟关闭事务..."); 52 return obj; 53 } 54 55 // 异常通知 56 @AfterThrowing(value = "myPoint()",throwing = "e") 57 public void myAfterThrowing(JoinPoint joinPoint, Throwable e) { 58 System.out.println("异常通知:" + "出错了" + e.getMessage()); 59 } 60 61 // 最终通知 62 @After("myPoint()") 63 public void myAfter() { 64 System.out.println("最终通知:模拟方法结束后的释放资源..."); 65 } 66 } 67 /** 68 * 提醒:同时记得jdk包下的目标类也要进行一个持久化层的一个注解的添加; 69 * */

    #接口、目标类:

    package com.sjl.jdk;
    
    public interface UserDao {
         void addUser();
         void deleteUser();
    }
    package com.sjl.jdk;
    
    import org.springframework.stereotype.Repository;
    
    /**
     * UserDaoImpl是目标类,对其中的方法进行增强处理;
     */
    @Repository("userDao")
    public class UserDaoImpl implements UserDao{
    
        @Override
        public void addUser() {
            System.out.println("添加用户");
        }
    
        @Override
        public void deleteUser() {
            System.out.println("删除用户");
        }
    }

    #配置文件的配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.3.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <!--指定需要扫描的包,使注解生效-->
        <context:component-scan base-package="com.sjl"/>
        <!--启动注解声明式AspectJ支持-->
        <aop:aspectj-autoproxy />
    </beans>

    #测试类

    package com.sjl.aspectj.annotation;
    
    import com.sjl.jdk.UserDao;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    //测试类
    public class TestAnnotationAspectj {
        public static void main(String[] args) {
            String xmlPath="applicationContext02Annotation.xml";
            ApplicationContext ac=new ClassPathXmlApplicationContext(xmlPath);
    //接口类型,向上造型 提高代码的复用性,其实也可以强转为父类,就强转为子类,
    // 但是复用性就差,因为后面如果还有其它的代码就不利于使用
    UserDao userDao=(UserDao)ac.getBean("userDao"); userDao.addUser();
    }
    }

    运行结果:

    环绕开始:执行目标方法之前,模拟开启事务...
    前置通知 :模拟执行权限检查...,目标类是:class com.sjl.jdk.UserDaoImpl,被织入增强处理的目标方法为:addUser
    添加用户
    环绕结束:执行目标方法之后,模拟关闭事务...
    最终通知:模拟方法结束后的释放资源...
    后置通知:模拟记录日志...,被织入增强处理的目标方法为:addUser

    说明:后置通知只有在目标方法成功执行之后才会被织入,而最终通知无论目标方法如何结束(包括异常中断)

    都会被织入。

    成年人的世界没有那么多的童话,也没有那么多的逆袭。
  • 相关阅读:
    HTTP报文详解
    常用的HTTP协议
    URL详解
    log4net工作原理(2)
    《Linux内核设计与实现》读书笔记(十七)- 设备与模块
    《Linux内核设计与实现》读书笔记(十六)- 页高速缓存和页回写
    《Linux内核设计与实现》读书笔记(十五)- 进程地址空间(kernel 2.6.32.60)
    《Linux内核设计与实现》读书笔记(十四)- 块I/O层
    随手记代码
    记录一下WPF中自寄宿asp.net服务添加urlacl的问题
  • 原文地址:https://www.cnblogs.com/shijinglu2018/p/10354792.html
Copyright © 2020-2023  润新知