Spring——几分钟掌握Aop核心术语

AOP官方术语(看看就行)

Aop术语;(七大主要)

切面(Aspect:)  xml中的bean元素指定的部分 横向插入系统的功能

连接点(joinpoint):   方法的调用

切入点(pointcut)   类或者方法名加入到所有以add开头的文件中

通知增强/增强处理(Advice) 切面类中方法

目标对象(TargetOjbect)  被通知的对象

代理(Proxy)切面应用到对应的目标对象中新创建的对象

织入(Weaving)

 

 

个人理解 ——AOP干货:

连接点提供方法供切入点选择;

切入点选择连接点中的部分想要实现的方法,在其前后或者抛出异常来进行通知 (连接点只是为了让你理解切点)

代理类实现和目标类一样的接口,变成接口的真正实现(运行时会以为自己就是目标类)

我做不了,但是你能做,我让你做,然后我在之前做了点别的事(日志啊什么的)   

你(目标类)我(代理类)   下面是详细的描述

(1)切面(Aspect):通知(advince)和切入点(pointcut)的结合

(2)连接点(JoinPoint): 由于spring只支持方法的连接点   所以spring允许你通知的地方   

和方法有关的前前后后(抛出异常)都是连接点

(3)切入点:连接点基础上筛选出你想要的去通知的方法,方法调用前后做点什么事

切点来选择对应的连接点       

例如:定义切点时一个类中有15个方法就有几十个连接点

简单来讲说白了根本没有连接点什么事情,最后选择通知的还是从其中选出来的我需要通知的几个作为切入点

他做的就是给切入点提供了需要的一种或几个方法

(4)advice增强通知  你想要的功能定义好想用的地方用一下,简单而言就是切面中类方法

(5)target目标 :引用中所提到的目标类也就是被通知的对象,真正的业务逻辑

(6)proxy代理类伪装成目标类,它会截取对目标类中方法的调用,让调用者对目标类的调用都先变成调用伪装类,伪装类中就先执行了切面,再把调用转发给真正的目标bean。 

需要实现

Proxy

Class A  Implements innovationHandler接口

public object createProxy(自己根据情况创建dao的对象)

ClassLoader classloarde = 类名.class..getClassloader();   //类加载器classloader

Class clazz = (dao文件).GetClass()。getInterface()    //获取所有结口

Return    Proxy.newProxyInstance(classLoader,clazz(实现的接口名),this)      //对应的参数都是上面自己写过的部分

Object   invoke    再对已经定义好的方法进行前后的调用处理即可

 

  Proxy实现的两种方式

  1. 实现和目标类相同的接口,我也实现和你一样的接口,反正上层都是接口级别的调用,这样我就伪装成了和目标类一样的类(实现了同一接口,咱是兄弟了),也就逃过了类型检查    (代理类实现目标类的所有方法,你只做你的,我去做别的)
  2. 生成子类调用,这次用子类来做为伪装类;子类重写了目标类的所有方法,当然在这些重写的方法中,不仅实现了目标类的功能,还在这些功能之前,实现了一些其他的(写日志,安全检查,事物等)。

(子类重写目标类的所有方法,子类去做我要做的事  子类相当于代理类)

不过父类的一些final方法儿子不能实现,不能实现的就不能调用伪装,不能实现松耦合

*********************************************************************

注解方式设置切入点:

@annotation 匹配连接点被它参数指定的Annotation注解的方法。也就是说,所有被指定注解标注的方法都将匹配。

            @Pointcut("@annotation(com.cjm.annotation.AdviceAnnotation)")

            public void before(){}

 @Around环绕通知:包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。

   环绕通知最麻烦,也最强大,其是一个对方法的环绕,具体方法会通过代理传递到切面中去,切面中可选择执行方法与否,执行方法几次等。

   环绕通知使用一个代理ProceedingJoinPoint类型的对象来管理目标对象,所以此通知的第一个参数必须是ProceedingJoinPoint类型,在通知体内,调用ProceedingJoinPointproceed()方法会导致后台的连接点方法执行。proceed 方法也可能会被调用并且传入一个Object[]对象-该数组中的值将被作为方法执行时的参数。

 

 

切入点表达式关键词:

   切入点表达式的格式:execution([可见性] 返回类型 [声明类型].方法名(参数) [异常])

  其中【】中的为可选,其他的还支持通配符的使用:

    *:匹配所有字符
      ..:一般用于匹配多个包,多个参数
      +:表示类及其子类

  运算符有:&&、||、!

 

args:用于将参数传入到通知方法中。

 @Before("before() && args(age,username)")
            public void beforeAdvide(JoinPoint point, int age, String username){                  //处理逻辑

 

 this:用于向通知方法中传入代理对象的引用。

            @Before("before() && this(proxy)")

            public void beforeAdvide(JoinPoint point, Object proxy){

                  //处理逻辑

 

execution:用于匹配子表达式。

            //匹配com.cjm.model包及其子包中所有类中的所有方法,返回类型任意,方法参数任意
            @Pointcut("execution(* com.cjm.model..*.*(..))")

            public void before(){}

 

Spring AOPSpring框架中的一个重要模块,它提供了面向切面编程(AOP)的支持。AOP是一种编程思想,它可以在不改变原有代码的情况下,通过在程序运行时动态地将代码“织入”到现有代码中,从而实现对原有代码的增强。 Spring AOP提供了基于注解的AOP实现,使得开发者可以通过注解的方式来定义切面、切点和通知等相关内容,从而简化了AOP的使用。 下面是一个基于注解的AOP实现的例子: 1. 定义切面类 ```java @Aspect @Component public class LogAspect { @Pointcut("@annotation(Log)") public void logPointcut() {} @Before("logPointcut()") public void beforeLog(JoinPoint joinPoint) { // 前置通知 System.out.println("执行方法:" + joinPoint.getSignature().getName()); } @AfterReturning("logPointcut()") public void afterLog(JoinPoint joinPoint) { // 后置通知 System.out.println("方法执行完成:" + joinPoint.getSignature().getName()); } @AfterThrowing(pointcut = "logPointcut()", throwing = "ex") public void afterThrowingLog(JoinPoint joinPoint, Exception ex) { // 异常通知 System.out.println("方法执行异常:" + joinPoint.getSignature().getName() + ",异常信息:" + ex.getMessage()); } } ``` 2. 定义业务逻辑类 ```java @Service public class UserService { @Log public void addUser(User user) { // 添加用户 System.out.println("添加用户:" + user.getName()); } @Log public void deleteUser(String userId) { // 删除用户 System.out.println("删除用户:" + userId); throw new RuntimeException("删除用户异常"); } } ``` 3. 在配置文件中开启AOP ```xml <aop:aspectj-autoproxy/> <context:component-scan base-package="com.example"/> ``` 在这个例子中,我们定义了一个切面类LogAspect,其中通过@Aspect注解定义了一个切面,通过@Pointcut注解定义了一个切点,通过@Before、@AfterReturning和@AfterThrowing注解分别定义了前置通知、后置通知和异常通知。 在业务逻辑类中,我们通过@Log注解标注了需要增强的方法。 最后,在配置文件中,我们通过<aop:aspectj-autoproxy/>开启了AOP功能,并通过<context:component-scan>扫描了指定包下的所有组件。 这样,当我们调用UserService中的方法时,就会触发LogAspect中定义的通知,从而实现对原有代码的增强。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值