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

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

都会被织入。

 

posted @ 2019-02-07 14:33  贰零一八  阅读(162)  评论(0编辑  收藏  举报