zoukankan      html  css  js  c++  java
  • AspectJ开发

    aspectJ 是基于java语言的aop框架,提供了强大的aop功能。

    aspectJ的实现主要有两种,一种是基于xml的声明式aspectJ,另一种是基于注解的aspectJ。

    1.基于xml的声明式aspectJ

    接口userDao 

    public interface userDao {
    public void addUser();
    public void deleteUser();
    }
    接口实现类UserDaoImp
    public class UserDaoImp implements userDao {
        @Override
    public void addUser() {
    System.out.println("添加用户");
    }
    @Override
    public void deleteUser() {
    System.out.println("删除用户");
    }
    }

    //切面类MyAspect

    public class MyAspect {
    //前置通知
    //JoinPoint连接点
    public void myBefore(JoinPoint joinPoint) {
    System.out.println("前置通知的目标类:" + joinPoint.getTarget());
    System.out.println("被植入增强的方法是:" + joinPoint.getSignature().getName());
    }

    //后置通知
    public void myAfterReturning(JoinPoint joinPoint) {
    System.out.println("后置通知,被植入增强的目标方法是:" + joinPoint.getSignature().getName());
    }

    /*环绕通知
    * ProceedingJoinPoint 是JoinPoint子接口,表示可执行目标方法
    * 类型必须是Object类型的返回值
    * 必须接收一个参数,类型为ProceedingJoinPoint
    * 必须抛出异常throws Throwable
    * */
    public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    System.out.println("环绕开始");
    //执行当前目标方法
    Object obj = proceedingJoinPoint.proceed();
    System.out.println("环绕结束");
    return obj;
    }

    //异常通知
    public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
    System.out.println("异常通知开始,出错了" + e.getMessage());
    }

    //最终通知
    public void myAfter() {
    System.out.println("最终通知,始终要执行");
    }
    }
    在xml中的配置
    <!-- 1 目标类 -->
    <bean id="userDao" class="com.itheima.ioc.aspectJ.UserDaoImp"/>
    <!-- 2 切面 -->
    <bean id="myAspect" class="com.itheima.ioc.aspectJ.MyAspect"/>
    <!-- 3 aop编程 -->
    <aop:config>
    <!-- 配置切面 -->
    <aop:aspect id="myaspect" ref="myAspect">
    <!-- 3.1 配置切入点,通知最后增强哪些方法 -->
    <aop:pointcut expression="execution(* com.itheima.ioc.aspectJ.*.*(..))"
    id="myPointCut"/>
    <!-- 3.2 关联通知Advice和切入点pointCut -->
    <!-- 3.2.1 前置通知 -->
    <aop:before method="myBefore" pointcut-ref="myPointCut"/>
    <!-- 3.2.2 后置通知,在方法返回之后执行,就可以获得返回值
    returning属性:用于设置后置通知的第二个参数的名称,类型是Object -->
    <aop:after-returning method="myAfterReturning"
    pointcut-ref="myPointCut" returning="joinPoint"/>
    <!-- 3.2.3 环绕通知 -->
    <aop:around method="myAround" pointcut-ref="myPointCut"/>
    <!-- 3.2.4 抛出通知:用于处理程序发生异常-->
    <!-- * 注意:如果程序没有异常,将不会执行增强 -->
    <!-- * throwing属性:用于设置通知第二个参数的名称,类型Throwable -->
    <aop:after-throwing method="myAfterThrowing"
    pointcut-ref="myPointCut" throwing="e"/>
    <!-- 3.2.5 最终通知:无论程序发生任何事情,都将执行 -->
    <aop:after method="myAfter" pointcut-ref="myPointCut"/>
    </aop:aspect>
    </aop:config>
    </beans>
    测试代码
    public class xmlAspectJTest {
    public static void main(String[] args) {
    ApplicationContext applicationContext =
    new ClassPathXmlApplicationContext("applicationContext.xml");
    userDao userdao = (userDao) applicationContext.getBean(userDao.class);
    userdao.deleteUser();
    // userdao.addUser();
    }
    }
    测试结果

    前置通知的目标类:com.itheima.ioc.aspectJ.UserDaoImp@291f18
    被植入增强的方法是:deleteUser
    环绕开始
    删除用户
    最终通知,始终要执行
    环绕结束
    后置通知,被植入增强的目标方法是:deleteUser

    2.基于注解的aspectJ


    @Aspect//注册声明切面
    @Component//将这个切面标示为spring中的bean

    public class MyAspect {
        //前置通知
    @Pointcut("execution(* com.itheima.ioc.aspectJ.*.*(..))")
    //使用一个返回值为空,方法体为空的方法来命名切入点
    //一般为私有的
    private void myPointCut(){}

    @Before("myPointCut()")
    public void myBefore(JoinPoint joinPoint) {
    System.out.println("前置通知的目标类:" + joinPoint.getTarget());
    System.out.println("被植入增强的方法是:" + joinPoint.getSignature().getName());
    }

    //后置通知
    @AfterReturning("myPointCut()")
    public void myAfterReturning(JoinPoint joinPoint) {
    System.out.println("后置通知,被植入增强的目标方法是:" + joinPoint.getSignature().getName());
    }

    /*环绕通知
    * ProceedingJoinPoint 是JoinPoint子接口,表示可执行目标方法
    * 类型必须是Object类型的返回值
    * 必须接收一个参数,类型为ProceedingJoinPoint
    * 必须抛出异常throws Throwable
    * */
    @Around("myPointCut()")
    public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    System.out.println("环绕开始");
    //执行当前目标方法
    //如果不调用则不执行目标方法
    Object obj = proceedingJoinPoint.proceed();
    System.out.println("环绕结束");
    return obj;
    }

    //异常通知
    @AfterThrowing(value = "myPointCut()",throwing = "e")
    public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
    System.out.println("异常通知开始,出错了" + e.getMessage());
    }

    //最终通知
    @After("myPointCut()")
    public void myAfter() {
    System.out.println("最终通知,始终要执行");
    }
    }
    接口Dao
    public interface Dao {
    public void addUser();
    public void deleteUser();
    }
    实现接口UserDaoImp 类
    @Repository("Dao")//spring注解,标示为spring中的bean,相当于在spring中的配置<bean id="Dao" class="类的全限定路径.UserDaoImp"/>

    public class UserDaoImp implements Dao {
    @Override
    public void addUser() {
    System.out.println("添加用户");
    }

    @Override
    public void deleteUser() {
    System.out.println("删除用户");
    }
    }

     在xml中的配置

    指定需要扫描的包

    <contxt:component-scan base-package="com.itheima.ioc"/>
    使注解生效
    <aop:aspectj-autoproxy/> 

     最后测试和基于xml声明的测试是一样的,结果也一样。

    
    
  • 相关阅读:
    BZOJ 1101 莫比乌斯函数+分块
    BZOJ 2045 容斥原理
    BZOJ 4636 (动态开节点)线段树
    BZOJ 2005 容斥原理
    BZOJ 2190 欧拉函数
    BZOJ 2818 欧拉函数
    BZOJ 3123 主席树 启发式合并
    812. Largest Triangle Area
    805. Split Array With Same Average
    794. Valid Tic-Tac-Toe State
  • 原文地址:https://www.cnblogs.com/jasonboren/p/10593398.html
Copyright © 2011-2022 走看看