Spring AOP和自定义注解

news/2024/7/7 14:39:01

用过Spring的朋友都知道,Spring有两大核心功能,一个是IOC,一个是AOP。IOC对于开发者来讲可能用的还比较多,声明一个Bean交给Spring容器来管理,或者从Spring容器中找到某个Bean注入到另一个Bean中。而对于AOP来讲,普通开发者用的就不是很多了。往往是项目的整体架构都已经对切面进行处理完毕了,记录日志也好,处理数据库事务也好等等这些功能,程序员一般是不需要关注的,当然这也是AOP的核心--关注点分离。这篇笔记并不是来记录如何使用AOP的,对于AOP的讲解网络上有很多的文章,可以参考。这里主要介绍的是使用Java配置的方式实现AOP,以及使用自定义注解

用一个实际的例子来演示使用注解和使用单纯的AOP的方式来面向切面编程。主要目标是实现在某个方法上打上我们自定义的注解,就可以被切面所拦截,在方法执行前或者方法执行后执行一些操作。

我们这里需要一个注解类,两个服务提供者,一个切面,再加一个配置类和一个运行的类,运行的类并充当服务的消费者。

注解类

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {

     String name();

}

这里定义了一个注解,表示是运行时生效,目标是标注在方法上。可以指定一个name属性。注解本身就是一个标记,是没有任何的功能的。

第一个服务的提供者,不使用注解  

@Service
public class DemoService {

     public void add() {

     }

}

这里就提供了一个空的add方法

第二个服务的提供者,使用注解

@Service
public class DemoAnnotationService {

     @Action(name="注解拦截的add操作")
     public void add() {

     }

}

这里和第一个服务的提供者类似,同样提供了一个空的add方法,只是在add方法上标注了我们定义的action注解,并指定了name属性的值

切面

@Aspect // 声明一个切面
@Component
public class LogAspect {

     // 关于切入点,可以单独定义,如下。也可以直接写在通知中。单独定义的可以复用,而写到通知中的不可以进行复用。类似于函数和匿名函数。 
     @Pointcut("@annotation(com.hy.spring.test3.Action)") // 定义一个切入点
     public void annotationPointCut() {}

     @Before("execution(* com.hy.spring.test3.DemoService.*(..))") // 定义一个前置通知,并制定切入点表达式
     public void begin(JoinPoint joinPoint) {
          MethodSignature signature = (MethodSignature) joinPoint.getSignature();
          Method method = signature.getMethod();

          System.out.println("方法规则式拦截 " + method.getName());
     }

     @After("annotationPointCut()") // 声明一个后置通知,并使用之前定义的切入点
     public void after (JoinPoint joinPoint) {
          MethodSignature signature = (MethodSignature) joinPoint.getSignature();

          Method method = signature.getMethod();
          Action action = method.getAnnotation(Action.class);
          System.out.println("注解式拦截 " + action.name());
     }

}

这个是我们的核心代码,先看注解,这里用到了Aspect,Component,Pointcut,Before,After。分别介绍这5个注解

Aspect

声明一个切面

Pointcut

声明切点

Before

声明前置通知

After

声明后置通知

Component

交给spring容器来管理

了解了注解的基本功能之后,再来对代码进行分析。如果对AOP不熟悉的小伙伴可以先了解一下AOP的相关内容,再来继续向下学习。这里其实就是两个通知,一个前置通知,一个后置通知,分别对应这两个切入点。切入点的配置方式有两种,第一种就是在前置通知中定义的形式,直接将切面表达式写到注解中,另外可以单独将切入点定义处理,并使用Pointcut来声明这个切入点表达式,方法的名字就是切点的名称。后置通知中就是使用的这种形式,在后置通知的注解中指定切点的方法名,这里一定要把方法的()加上,否则找不到切点。切点表达式定义的都非常简单,annotationPointCut()切点就是要切带有com.hy.spring.test3.Action这个注解的所有类, @Before("execution(* com.hy.spring.test3.DemoService.*(..))")要切的就是com.hy.spring.test3.DemoService这个包下的所有类。下面我们再来看切了之后干的啥事,不难发现,做的事情也是非常的简单,带有注解的就是打印了注解中配置的值,没有注解的就打印了方法的名字。

配置类

@Configuration
@ComponentScan(value= "com.hy.spring.test3")
@EnableAspectJAutoProxy // 这里很关键,必须要开启对AOP的支持
public class AopConfig {

}

ComponentScan是要扫描的包,这个注解会自动扫描指定包下的所有的类

EnableAspectJAutoProxy是开启切面的自动代理

测试类

public class Main {

     public static void main(String[] args) {
          AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);

          DemoAnnotationService service = context.getBean(DemoAnnotationService.class);
          service.add();

          context.close();
     }

}

这里只演示了注解的切面,非注解的同样。


http://www.niftyadmin.cn/n/1896808.html

相关文章

兴趣是个伪命题

2019独角兽企业重金招聘Python工程师标准>>> 有些人在选择职业的时候,会强调自己是否感兴趣。 1.对行业感兴趣? 可能只是看到这个行业的前景,对潜在的回报感兴趣。 或者对于从事一个热门行业的那种被关注和认可感兴趣。 2.对于某职…

python字典索引没有的元素_Python中有没有一种方法可以通过容器的元素来索引容器列表(元组、列表、字典)?...

我一直在寻找一个方法/示例来索引元组列表,而不需要修改decorate、sort和uncorate方法。在例如:l[(a,b,c),(x,c,b),(z,c,b),(z,c,d),(a,d,d),(x,d,c) . . .]我一直使用的方法是使用第二个元素的defaultdict构建一个字典^{pr2}$然后,我必须为列…

android studio 模拟器无法联网的解决方法

本人环境 win10 64位 android studio 自带的模拟器 1、首先把模拟器打开,然后需要把SDK文件夹下的platform-tools添加到系统变量中(此目录一定要不要弄错)。 2、怎么检查自己是否添加成功呢,在cmd中输入:adb shell 回…

sonar mysql svn_Tomcat+Jenkins+SonarQube+SVN+Maven 集成自动化环境搭建(Windows10环境下)

说在前面的话: 从接到任务到完成共用了7天的时间。正常人用不到这个时间。 此时的功能表现是: 登录本地JenKins对项目进行构建,能够自动从SVN读取最新代码并按照Maven项目构建,构建完成能够自动使用SonarQube分析代码质量&#xf…

java正则表达式移除网页中注释代码

/** * 移除网页中注释掉的代码 * * param str * return */ public static String removedisablecode(String str) { Pattern pattern Pattern.compile("<!--[\\w\\W\r\\n]*?-->"); Matcher matcher pattern.matcher(str); str matcher.replaceAll("&…

非对称加密的典型应用

1.数字签名 对摘要信息进行加密&#xff0c;这样做就能保证原文与公钥的一致性。 2.保密通讯&#xff08;SSL与HTTPS&#xff09; 实际上是使用非对称加密传递对称加密的密钥。 转载于:https://my.oschina.net/chunquedong/blog/54348

最快最简单的部署本地Apache+PHP+MySQL神器USBWebserver(转)

搭建本地服务器环境的软件有很多&#xff0c;比如什么PHPNOW、Almp、XAMPP等等好多&#xff1b;<br> 之前分享过一个《网站本地搭建PHP&#xff0b;Mysql环境运行网站教程》用是PHPnow&#xff1b; 今天分享的是USBWebserver&#xff0c;名字中USB就说明它是一款便携式环…

2883 -- 【TJOI2018】游园会

Description 小豆参加了\(NOI\)的游园会&#xff0c;会场上每完成一个项目就会获得一个奖章&#xff0c;奖章只会是\(N,O,I\)的字样。在会场。上他收集到了\(K\)个奖章组成的串。兑奖规则是奖章串和兑奖串的最长公共子序列长度为小豆最后奖励的等级。现在已知兑奖串长度为N&…