Spring入门篇 学习笔记

@AspectJ 的风格类似纯 java 注解的普通 java 类

Spring 可以使用 AspectJ 来做切入点解析

AOP 的运行时仍旧是纯的 Spring AOP, 对 AspectJ 的编译器或者织入无依赖性

Spring 中配置 @AspectJ

对 @AspectJ 支持可以使用 XML 或 Java 风格的配置

<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="com.karonda.aop.aspectj"/>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>

确保 AspectJ 的 aspectjweaver.jar (1.6.8或更高版本) 库包含在应用程序的 classpath 中

aspect

@AspectJ 切面使用 @Aspect 注解配置,拥有 @Aspect 的任何 bean 将被 Spring 自动识别并应用

用 @Aspect 注解的类可以有方法和字段,他们也可能包括切入点、通知和引入的声明

@Aspect 注解是不能通过类路径自动检测发现的,所以需要配合使用 @Component 注释或者在 XML 配置 bean

一个类中的 @Aspect 注解标识它为一个切面,并且将自己从自动代理中排除

@Component
@Aspect
public class MoocAspect { }

pointcut

一个切入点通过一个普通的方法定义来提供,并且切入点表达式使用 @Pointcut 注解,方法返回类型必须为 void

@Component
@Aspect
public class MoocAspect { @Pointcut("execution(* com.karonda.aop.aspectj.biz.*Biz.*(..))")
public void pointcut() {} @Pointcut("within(com.karonda.aop.aspectj.biz.*)")
public void bizPointcut() {} }

组合 pointcut

切入点表达式可以通过 &&, || 和 ! 进行组合,也可以通过名字引用切入点表达式

通过组合,可以建立更加复杂的切入点表达式

定义良好的 pointcut

AspectJ 是编译期的 AOP

检查代码并匹配连接点与切入点的代价是昂贵的

一个好的切入点应该包括以下几点:

  • 选择特定类型的连接点,如:execution, get, set, call, handler
  • 确定连接点范围,如:within, withincode
  • 匹配上下文信息,如:this, target, @annotation

advice

添加类:

@Service
public class MoocBiz { public String save(String arg) {
System.out.println("MoocBiz save : " + arg);
// throw new RuntimeException(" Save failed!");
return " Save success!";
} }

添加测试类:

@RunWith(BlockJUnit4ClassRunner.class)
public class TestAspectJ extends UnitTestBase { public TestAspectJ() {
super("classpath:spring-aop-aspectj.xml");
} @Test
public void test() {
MoocBiz biz = getBean("moocBiz");
biz.save("This is test.");
} }

Before advice

在 MoocAspect 类添加方法:

//	@Before("execution(* com.karonda.aop.aspectj.biz.*Biz.*(..))")
@Before("pointcut()")
public void before() {
System.out.println("Before.");
}

After returning advice

	@AfterReturning(pointcut="bizPointcut()", returning="returnValue")
public void afterReturning(Object returnValue) {
System.out.println("AfterReturning : " + returnValue);
}

After throwing advice

	@AfterThrowing(pointcut="pointcut()", throwing="e")
public void afterThrowing(RuntimeException e) {
System.out.println("AfterThrowing : " + e.getMessage());
}

After (finally) advice

最终通知必须准备处理正常和异常两种返回情况,它通常用于释放资源

	@After("pointcut()")
public void after() {
System.out.println("After.");
}

Around advice

	@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("Around 1.");
Object obj = pjp.proceed();
System.out.println("Around 2.");
System.out.println("Around : " + obj);
return obj;
}

advice 扩展

给 advice 传递参数

args

	@Before("pointcut() && args(arg)")
public void beforeWithParam(String arg) {
System.out.println("BeforeWithParam." + arg);
}

annotation

可以用来判断方法上是否加了某注解或者方法上加的注解对应的值

定义一个注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MoocMethod { String value(); }

添加注解;

@Service
public class MoocBiz { @MoocMethod("MoocBiz save MoocMethod.")
public String save(String arg) {
System.out.println("MoocBiz save : " + arg);
// throw new RuntimeException(" Save failed!");
return " Save success!";
} }

添加通知:

@Before("pointcut() && @annotation(moocMethod)")
public void beforeWithAnnotaion(MoocMethod moocMethod) {
System.out.println("BeforeWithAnnotation." + moocMethod.value());
}

advice 的参数及泛型

public interface Sample<T>{
void sampleGenericMethod (T param);
void sampleGenericCollectionMethod (Collection<T> param);
} @Before("execution(* ..Sample+.sampleGenericMethod(*)) && args(param)")
public void beforeSampleMethod(MyType param){ } @Before("execution(* ..Sample+.sampleGenericCollectionMethod(*)) && args(param)")
public void beforeSampleMethod(Collection<MyType> param){
}

advice 参数名称

通知和切入点注解有一个额外的 argNames 属性,它可以用来指定所注解的方法的参数名

@Before(value="com.xyz.lib.Pointcuts.anyPublicMethod() && target(bean) && annotation(auditable)", argNames="bean,auditable")
public void audit(Object bean, Auditable a)

如果第一个参数是 JoinPoint, ProceedingJoinPoint, JoinPoint.StaticPart 那么可以忽略它

@Before(value="com.xyz.lib.Pointcuts.anyPublicMethod() && target(bean) && annotation(auditable)", argNames="bean,auditable")
public void audit(JoinPoint jp, Object bean, Auditable a)

Introduction

允许一个切面声明一个通知对象实现指定接口,并且提供了一个接口实现类来代表这些对象

introduction 使用 @DeclareParents 进行注解,这个注解用来定义匹配的类型拥有一个新的 parent

@Aspect
public class UsageTracking{
@DeclareParents(value="com.xyz.myapp.service.*+", defaultImpl=DefaultUsageTracked.class)
public class UsageTracked mixin; @Before("com.xyz.myapp.SystemArchitecture.businessService() && this(usageTracked)")
public void recordUsage(UsageTracked usageTracked) {
usageTracked.incrementUseCount();
}
}

切面实例化模型

perthis 切面通过指定 @Aspect 注解 perthis 子句实现

每个独立的 service 对象执行时都会创建一个切面实例

service 对象的每个方法在第一次执行的时候创建切面实例,切面在 service 对象失效的同时失效

@Aspect("perthis(com.xyz.myapp.SystemArchitecture.businessService())")
public class MyAspect{
private int someState; @Before(com.xyz.myapp.SystemArchitecture.businessService())
public void recordServiceUsage(){ } }

源码:learning-spring

学习 Spring (十七) Spring 对 AspectJ 的支持 (完结)的更多相关文章

  1. 学习Spring-Data-Jpa(十七)---对Web模块的支持

    Spring-Data还提供了Web模块的支持,这要求Web组件Spring-MVC的jar包位于classpath下.通常通过使用@EnableSpringDataWebSupport注解来启用继承 ...

  2. (转)实例简述Spring AOP之间对AspectJ语法的支持(转)

    Spring的AOP可以通过对@AspectJ注解的支持和在XML中配置来实现,本文通过实例简述如何在Spring中使用AspectJ.一:使用AspectJ注解:1,启用对AspectJ的支持:通过 ...

  3. Java缓存学习之五:spring 对缓存的支持

    (注意标题,Spring对缓存的支持 这里不单单指Ehcache ) 从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache ...

  4. Spring入门篇——第7章 Spring对AspectJ的支持

    第7章 Spring对AspectJ的支持 介绍Spring对AspectJ的支持 7-1 AspectJ介绍及Pointcut注解应用 实例 完成了在xml文件的配置 7-2 Advice定义及实例 ...

  5. [Spring学习笔记 7 ] Spring中的数据库支持 RowMapper,JdbcDaoSupport 和 事务处理Transaction

    1.Spring中的数据库支持 把具有相同功能的代码模板抽取到一个工具类中.2.关于jdbc template的应用 jdbcTemplate模板操作类,把访问jdbc的模板抽取到template中, ...

  6. Spring学习(二):Spring支持的5种Bean Scope

    序言 Scope是定义Spring如何创建bean的实例的.Spring容器最初提供了两种bean的scope类型:singleton和prototype,但发布2.0以后,又引入了另外三种scope ...

  7. spring(二) AOP之AspectJ框架的使用

    前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么.而今天要学习spring的第二个重点,AOP.一篇讲解不完,所以 ...

  8. SSM(spring mvc+spring+mybatis)学习路径——1-2、spring事务管理

    目录 1-2 Spring事务管理 概念介绍 事务回顾 事务的API介绍 Spring 事务管理 转账案例 编程式事务管理 声明式事务管理 使用XML配置声明式事务 基于tx/aop 使用注解配置声明 ...

  9. SSM(spring mvc+spring+mybatis)学习路径——1-1、spring入门篇

    目录 1-1 Spring入门篇 专题一.IOC 接口及面向接口编程 什么是IOC Spring的Bean配置 Bean的初始化 Spring的常用注入方式 专题二.Bean Bean配置项 Bean ...

随机推荐

  1. 线程的synchronized、volatile及原子操作

    public class ThreadDemo7{ //structs2线程不安全 共享变量 //n++ 复合操作 对于volatile修饰的变量不安全 //原子操作 int value; //让方法 ...

  2. [MicroPython]STM32F407开发板DIY声光控开关

    1.实验目的 1. 学习在PC机系统中扩展简单I/O 接口的方法. 2. 进一步学习编制数据输出程序的设计方法. 3. 学习光敏模块的工作原理. 4. 学习声音的工作原理. 5. 学习F40 7Mic ...

  3. 有一个IT男友是怎么样体验呢?

      前言:          一提到IT男,大家就会惯性的给他贴上无趣,情商低,屌丝,技术宅的的等标签.那么作为一个IT男的女友到底是什么样的体验呢? 礼物:         别人的男朋友送礼物,一般 ...

  4. 跨语言调用Hangfire定时作业服务

    跨语言调用Hangfire定时作业服务 背景 Hangfire允许您以非常简单但可靠的方式执行后台定时任务的工作.内置对任务的可视化操作.非常方便. 但令人遗憾的是普遍都是业务代码和hagnfire服 ...

  5. 蛙蛙推荐: TensorFlow Hello World 之平面拟合

    tensorflow 已经发布了 2.0 alpha 版本,所以是时候学一波 tf 了.官方教程有个平面拟合的类似Hello World的例子,但没什么解释,新手理解起来比较困难. 所以本文对这个案例 ...

  6. 295B - Greg and Graph (floyd逆序处理)

    题意:给出任意两点之间的距离,然后逐个删除这些点和与点相连的边,问,在每次删除前的所有点对的最短距离之和 分析:首先想到的是floyd,但是如果从前往后处理,复杂度是(500)^4,超时,我们从后往前 ...

  7. echarts x轴 增加滚动条

    charts x轴 增加滚动条 在option 配置项中添加 [ dataZoom 中配置 ] 设置x轴滚动条 效果图: 动态拖动 以下参考代码 dataZoom配置 官网写法 option = { ...

  8. 使用redis限制ip访问次数

    策略1: 在redis中保存一个count值(int),key为user:$ip,value为该ip访问的次数,第一次设置key的时候,设置expires. count加1之前,判断是否key是否存在 ...

  9. hadoop实例-网站用户行为分析

    一.数据集 网站用户购物行为数据集2030万条,包括raw_user.csv(2000万条)和small_user.csv(30万条,适合新手) 字段说明: user_id 用户编号,item_id ...

  10. 解决sqoop连接mysq错误

    一.问题描述 1.由于当前集群没有配置Zookeeper.hcatalog.accumlo,因此应该在sqoop的配置文件中注释掉判断Zookeeper.hcatalog.accumlo路径是否正确的 ...