选择切点

  Spring是方法级别的AOP框架,而我们主要也是以某个类的某个方法作为切点,用动态代理的理论来说,就是要拦截哪个方法织入对应AOP通知。
  代码清单:打印角色接口

package com.ssm.chapter11.aop.service;

import com.ssm.chapter11.game.pojo.Role;

public interface RoleService {

    // public void printRole(Role role);

    public void printRole(Role role, int sort);

}

  代码清单:RoleService实现类

package com.ssm.chapter11.aop.service.impl;

import org.springframework.stereotype.Component;
import com.ssm.chapter11.aop.service.RoleService;
import com.ssm.chapter11.game.pojo.Role; @Component
public class RoleServiceImpl implements RoleService { // @Override
// public void printRole(Role role) {
// System.out.println("{id: " + role.getId() + ", " + "role_name : " + role.getRoleName() + ", " + "note : " + role.getNote() + "}");
// } public void printRole(Role role, int sort) {
System.out.println("{id: " + role.getId() + ", " + "role_name : " + role.getRoleName() + ", " + "note : " + role.getNote() + "}");
System.out.println(sort);
} }

  这个类没什么特别的,只是这个时候如果把printRole作为AOP的切点,那么用动态代理的语言就是要为类RoleServi-ceImpl生成代理对象,然后拦截printRole方法,于是可以产生各种AOP通知方法。

创建切面

  选择好了切点就可以创建切面了,对于动态代理的概念而言,它就如同一个拦截器,在Spring中只要使用@Aspect注解一个类,那么Spring IoC容器就会认为这是一个切面了

package com.ssm.chapter11.aop.aspect;

import com.ssm.chapter11.aop.verifier.RoleVerifier;
import com.ssm.chapter11.aop.verifier.impl.RoleVerifierImpl;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*; @Aspect
public class RoleAspect { @DeclareParents(value = "com.ssm.chapter11.aop.service.impl.RoleServiceImpl+", defaultImpl = RoleVerifierImpl.class)
public RoleVerifier roleVerifier; @Pointcut("execution(* com.ssm.chapter11.aop.service.impl.RoleServiceImpl.printRole(..))")
public void print() {
} // @Before("execution(* com.ssm.chapter11.aop.service.impl.RoleServiceImpl.printRole(..))")
// @Before("execution(* com.ssm.chapter11.*.*.*.*.printRole(..)) && within(com.ssm.chapter11.aop.service.impl.*)")
@Before("print()")
// @Before("execution(* com.ssm.chapter11.aop.service.impl.RoleServiceImpl.printRole(..)) && args(role, sort)")
public void before() {
System.out.println("before ....");
} @After("execution(* com.ssm.chapter11.aop.service.impl.RoleServiceImpl.printRole(..))")
public void after() {
System.out.println("after ....");
} @AfterReturning("execution(* com.ssm.chapter11.aop.service.impl.RoleServiceImpl.printRole(..))")
public void afterReturning() {
System.out.println("afterReturning ....");
} @AfterThrowing("execution(* com.ssm.chapter11.aop.service.impl.RoleServiceImpl.printRole(..))")
public void afterThrowing() {
System.out.println("afterThrowing ....");
} @Around("print()")
public void around(ProceedingJoinPoint jp) {
System.out.println("around before ....");
try {
jp.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("around after ....");
} }

连接点

  Spring是如何判断是否需要拦截方法的,毕竟并不是所有的方法都需要使用AOP编程,这就是一个连接点的问题。在注解中定义了execution的正则表达式,Spring是通过这个正则表达式判断是否需要拦截你的方法的,这个表达式是:
  execution(* com.ssm.chapter11.aop.service.impl.RoleServiceImpl.printRole(..))
  依次对这个表达式做出分析。
  •execution:代表执行方法的时候会触发。
  •*:代表任意返回类型的方法。
  •com.ssm.chapter11.aop.service.impl.RoleServiceImpl:代表类的全限定名。
  •printRole:被拦截方法名称。
  •(..):任意的参数。
  显然通过上面的描述,全限定名为com.ssm.chapter11.aop.service.impl.RoleServiceImpl的类的printRole方法被拦截了,这样它就按照AOP通知的规则把方法织入流程中。

测试AOP

  代码清单:配置Spring bean

package com.ssm.chapter11.aop.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import com.ssm.chapter11.aop.aspect.RoleAspect; @Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.ssm.chapter11.aop")
public class AopConfig { @Bean
public RoleAspect getRoleAspect() {
return new RoleAspect();
} }

  Spring还提供了XML的方式,这里就需要使用AOP的命名空间了

<?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.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"> <aop:aspectj-autoproxy/>
<bean id="roleAspect" class="com.ssm.chapter11.aop.aspect.RoleAspect"/>
<bean id="roleService" class="com.ssm.chapter11.aop.service.impl.RoleServiceImpl"/> </beans>

  无论用XML还是用Java的配置,都能使Spring产生动态代理对象,从而组织切面,把各类通知织入到流程当中

  代码清单:测试AOP流程

package com.ssm.chapter11.aop.main;

import com.ssm.chapter11.aop.verifier.RoleVerifier;
import com.ssm.chapter11.aop.verifier.impl.RoleVerifierImpl;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.ssm.chapter11.aop.config.AopConfig;
import com.ssm.chapter11.aop.service.RoleService;
import com.ssm.chapter11.game.pojo.Role; public class Main { public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(AopConfig.class);
// 使用XML使用ClassPathXmlApplicationContext作为IoC容器
// ApplicationContext ctx = new ClassPathXmlApplicationContext("ssm/chapter11/spring-cfg3.xml");
RoleService roleService = ctx.getBean(RoleService.class); Role role = new Role();
role.setId(1L);
role.setRoleName("role_name_1");
role.setNote("note_1"); RoleVerifier roleVerifier = (RoleVerifier) roleService;
if (roleVerifier.verify(role)) {
roleService.printRole(role, 1);
}
System.out.println("####################");
//测试异常通知
// role = null;
// roleService.printRole(role);
} }

spring 使用@AspectJ注解开发Spring AOP的更多相关文章

  1. Spring学习之旅(八)Spring 基于AspectJ注解配置的AOP编程工作原理初探

    由小编的上篇博文可以一窥基于AspectJ注解配置的AOP编程实现. 本文一下未贴出的相关代码示例请关注小编的上篇博文<Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AO ...

  2. 使用@AspectJ注解开发Spring AOP

    一.实体类: Role public class Role { private int id; private String roleName; private String note; @Overr ...

  3. Spring Aop(二)——基于Aspectj注解的Spring Aop简单实现

    转发地址:https://www.iteye.com/blog/elim-2394762 2 基于Aspectj注解的Spring Aop简单实现 Spring Aop是基于Aop框架Aspectj实 ...

  4. Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AOP编程比较

    本篇博文用一个稍复杂点的案例来对比一下基于XML配置与基于AspectJ注解配置的AOP编程的不同. 相关引入包等Spring  AOP编程准备,请参考小编的其他博文,这里不再赘述. 案例要求: 写一 ...

  5. spring boot纯注解开发模板

    简介 spring boot纯注解开发模板 创建项目 pom.xml导入所需依赖 点击查看源码 <dependencies> <dependency> <groupId& ...

  6. Spring:基于注解的Spring MVC

    什么是Spring MVC Spring MVC框架是一个MVC框架,通过实现Model-View-Controller模式来很好地将数据.业务与展现进行分离.从这样一个角度来说,Spring MVC ...

  7. Spring自动装配----注解装配----Spring自带的@Autowired注解

    Spring自动装配----注解装配----Spring自带的@Autowired注解 父类 package cn.ychx; public interface Person { public voi ...

  8. Spring使用AspectJ注解和XML配置实现AOP

    本文演示的是Spring中使用AspectJ注解和XML配置两种方式实现AOP 下面是使用AspectJ注解实现AOP的Java Project首先是位于classpath下的applicationC ...

  9. Spring注解开发系列Ⅵ --- AOP&事务

    注解开发 --- AOP AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,横向重复,纵向抽取.详细的AO ...

随机推荐

  1. .NetCore WebApi结构及前端访问方式

    .NetCore WebApi结构及前端访问方式(Ajax方式,fetch方式,axios方式) //访问的地址api/控制器名称/方法名称;action一般会省略 [Route("api/ ...

  2. (三)IDEA使用,功能面板

    IDEA 打开界面后周围有许多的功能面板 常用的界面 1.project:项目的目录结构: 2.Structure:结构界面:在这个界面里可以看到选择的类,接口 的结构,有哪些方法,字段,等: 3. ...

  3. HiveQL Index 索引

    Hive只有有限的索引功能.Hive中没有普通关系型数据库中键的概念,但是还是可以对一些字段建立索引来加速某些操作.一张表的索引数据存储在另外一张表中. 通过explain命令可以查看某个查询语句是否 ...

  4. 4-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案升级篇(远程升级WIFI内部程序)

    https://www.cnblogs.com/yangfengwu/p/10360618.html 演示视频: https://www.bilibili.com/video/av54894356/ ...

  5. 2-使用git管理一个单片机程序

    https://www.cnblogs.com/yangfengwu/p/10842205.html 我用电脑压缩一个文件,然后通过git上传,然后在新买的linux系统通过wget 网络下载这个压缩 ...

  6. Linux下搭建iSCSI共享存储的方法 TGT 方式 CentOS6.9系统下

    iSCSI(internet SCSI)技术由IBM公司研究开发,是一个供硬件设备使用的.可以在IP协议的上层运行的SCSI指令集,这种指令集合可以实现在IP网络上运行SCSI协议,使其能够在诸如高速 ...

  7. GDB的安装

    1.下载GDB7.10.1安装包 #wget http://ftp.gnu.org/gnu/gdb/gdb-7.10.1.tar.gz或者可以远程看下有哪些版本 http://ftp.gnu.org/ ...

  8. typescript 错误记录

    经常遇到 typescript 的编译错误,虽然可以绕过去,不过既然采用了,还是解决问题,了解其中的思想比较重要. 一般遇到错误码 error TS2304: Cannot find name ... ...

  9. CF1188B/E Count Pairs(数学)

    数同余的个数显然是要把\(i,j\)分别放到\(\equiv\)的两边 $ (a_i + a_j)(a_i^2 + a_j^2) \equiv k \bmod p $ 左右两边乘上\((a_i-a_j ...

  10. 你未必知道的49个CSS知识点

    作者:老姚,<JS正则迷你书>的作者 https://github.com/qdlaoyao/css-gif 本文的每一条,都是我曾经发过的掘金沸点,其中有很多条超过了百赞(窃喜).鉴于时 ...