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声明的测试是一样的,结果也一样。

    
    
  • 相关阅读:
    fitnesse的安装
    elasticsearh 迁移
    网络基础之 二层三层网络通讯
    ansible 基本使用之3 palybook
    ansible-基本使用-2
    ansible 基本使用-1
    k8s 机器搭建之etcd
    http 状态码之3xx
    mysql 主从相关
    redis 主从及哨兵模式
  • 原文地址:https://www.cnblogs.com/jasonboren/p/10593398.html
Copyright © 2011-2022 走看看