AspectJ |
使用AOP的几种方式:
1.经典的基于代理的AOP
2.@AspectJ注解驱动的切面
3.纯POJO切面(纯粹通过<aop:fonfig>标签配置)
4.注入式AspectJ切面
用途
Authentication 权限
Caching 缓存
Context passing 内容传递
Error handling 错误处理
Lazy loading 懒加载
Debugging 调试
logging, tracing, profiling and monitoring 记录跟踪 优化 校准
Performance optimization 性能优化
Persistence 持久化
Resource pooling 资源池
Synchronization 同步
Transactions 事务
AOP 领域中的特性术语:
通知(Advice): AOP 框架中的增强处理。通知描述了切面何时执行以及如何执行增强处理。
连接点(join point): 连接点表示应用执行过程中能够插入切面的一个点,这个点可以是方法的调用、异常的抛出。在 Spring AOP 中,连接点总是方法的调用。
切点(PointCut): 可以插入增强处理的连接点。
切面(Aspect): 切面是通知和切点的结合。
引入(Introduction):引入允许我们向现有的类添加新的方法或者属性。
织入(Weaving): 将增强处理添加到目标对象中,并创建一个被增强的对象,这个过程就是织入。
扩展
切点匹配表达式:
execution:可以定义到方法的的最小粒度是参数的返回类型,修饰符,包名,类名,方法名,Spring AOP主要也是使用这个匹配表达式。
within:只能定义到类
this:当前生成的代理对象的类型匹配
target:目标对象类型匹配
args:只针对参数
execution和within的区别:
他们的主要区别就是粒度,within主要是辅助,为了健全而存在的。
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
方法的可见性(不写代表所有)?方法的返回类型 方法所在类的全路径名 ?方法名类型(方法的参数类型) 方法抛出的异常类型?
什么是AOP
1. 面向切面编程Aspect-Oriented-Programming
a) 是对面向对象的思维方式的有力补充
2. Spring_1400_AOP_Introduction
3. 好处:可以动态的添加和删除在切面上的逻辑而不影响原来的执行代码
a) Filter
b) Struts2的interceptor
4. 概念:
a) JoinPoint
b) PointCut
c) Aspect(切面)
d) Advice
e) Target
f) Weave
Spring AOP配置与应用
1. 两种方式:
a) 使用Annotation
b) 使用xml
2. Annotation
a) 加上对应的xsd文件spring-aop.xsd
b) beans.xml <aop:aspectj-autoproxy />
c) 此时就可以解析对应的Annotation了
d) 建立我们的拦截类
e) 用@Aspect注解这个类
f) 建立处理方法
g) 用@Before来注解方法
h) 写明白切入点(execution …….)
i) 让spring对我们的拦截器类进行管理@Component
3. 常见的Annotation:
a) @Pointcut
b) @Before
c) @AfterReturning
d) @AfterThrowing
e) @After
f) @Around
4. 织入点语法
a) void !void
b) 参考文档(* ..)
5. xml配置AOP
a) 把interceptor对象初始化
b) <aop:config
i. <aop:aspect …..
1. <aop:pointcut
2. <aop:before
网上一个例子:
一个切面类注解
@Before("execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))"
package com.sharpcj.aopdemo.test1;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class BuyAspectJ {
@Before("execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))")
public void haha(){
System.out.println("男孩女孩都买自己喜欢的东西");
}
}
这个类,我们使用了注解
@Component 表明它将作为一个Spring Bean 被装配(也就是一个组件交给Spring容器初始化),使用注解
@Aspect 表示它是一个切面。类中只有一个方法 haha 我们使用 @Before 这个注解,表示他将在方法执行之前执行。
参数("execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))") 声明了切点,表明在该切面的切点是com.sharpcj.aopdemo.test1.Ibuy这个接口中的buy方法。
另一个例子:
/*
@Aspect //声明是一个切面类,在编译成字节码时生产相关AOP代码
@Component //声明是个组件 会被Spring容器自动初始化 (必须初始化)
@Pointcut("execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))") //声明方法织入点这个包 com.sharpcj.aopdemo.test1.IBuy 下的buy方法将被织入 此处声明的时一个通用切点方法;
@Before("point()") //实际织入切点的方法会在执行前执行次方法;
@After("point()") //实际织入切点的方法会在执完毕后执行次方法;
@AfterReturning("point()") //实际织入切点的方法会在执完在返回值时后执行次方法
@Around("point()") //织入执行前后执行的方法
重点是这个声明
@Pointcut("execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))") //声明方法织入点这个包 com.sharpcj.aopdemo.test1.IBuy 下的buy方法将被织入 此处声明的时一个通用切点方法
public void point(){}
*/
//一个切面类 BuyAspectJ.java
package com.sharpcj.aopdemo.test1;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect //声明是一个切面类,在编译成字节码时生产相关AOP代码
@Component //声明是个组件 会被Spring容器自动初始化 (必须初始化)
public class BuyAspectJ {
@Pointcut("execution(* com.sharpcj.aopdemo.test1.IBuy.buy(..))") //声明方法织入点这个包 com.sharpcj.aopdemo.test1.IBuy 下的buy方法将被织入 此处声明的时一个通用切点方法
public void point(){}
@Before("point()") //实际织入切点的方法会在执行前执行次方法
public void hehe() {
System.out.println("before ...");
}
@After("point()") //实际织入切点的方法会在执完毕后执行次方法
public void haha() {
System.out.println("After ...");
}
@AfterReturning("point()") //实际织入切点的方法会在执完在返回值时后执行次方法
public void xixi() {
System.out.println("AfterReturning ...");
}
@Around("point()") //织入执行前后
public void xxx(ProceedingJoinPoint pj) {
try {
System.out.println("Around aaa ...");
pj.proceed();
System.out.println("Around bbb ...");
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
//一个测试类 AnnotationAOP.java
package com.sharpcj.aopdemo;
import com.sharpcj.aopdemo.test1.Boy;
import com.sharpcj.aopdemo.test1.Girl;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AnnotationAOP {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Boy boy = context.getBean("boy",Boy.class);
Girl girl = (Girl) context.getBean("girl");
boy.buy();
// girl.buy();
}
}