Spring AOP

AspectJ
类似拦截器在方法执行前后织入某些操作过程是一种称为"横切"的技术;一般通过代理实现;动态代理和静态代理;
代理一般由 JDK 自带 proxy() 和 InvocationHandler 实现;也可以由CGlib 直接生成字节码


JDK自带的动态代理主要是指,实现了InvocationHandler接口的代理类,实现了InvocationHandler接口的类,会继承一个invoke方法,通过在这个方法中添加某些代码,从而完成在方法前后添加一些动态的东西。JDK自带的动态代理依赖于接口,如果有些类没有接口,则不能实现动态代理。

 

 

使用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();

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值