SpringAop(2)

切点表达式:

 

自定义注解annotation:

在新建java类中选择Annotation,并创建对象。

package com.syx.aop.config;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAspect {
}

@Target后边的是作用域的范围,说明了后边是作用在方法上的。@Retention是作用的生命周期,(RUNTIME)是运行时。

但是这时候的注解并没有任何逻辑我们给他填上逻辑。

package com.syx.aop.aspect;

import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Component
@Slf4j
@Aspect
public class MyAspectDemo {
    //切点作用域
    @Around("@annotation(com.syx.aop.config.MyAspect)")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("do before........");
        Object proceed = joinPoint.proceed();
        log.info("do after..........");
        return proceed;


    }
}

在这里我们定义了一个切面类,通过@Around("@annotation(com.syx.aop.config.MyAspect)")来声明该切面类的作用范围。

这样就能通过加在方法上面自定义注解。       

这样写就是对所有的RequestMapping生效。只要使用RequestMapping注解的全部都生效

面试题:SpringAop的实现方式:

  1. 代理模式(比较原始不做过多阐述)。
  2. 使用SpringApi模式(xml配置后来进化成注解)。<aop:config>,配置方法
  3. 自定义类的方式(也是xml)<aop:config>,配置切面类 
  4. 基于@Aspect注解{1.基于execution表达式}{2.基于自定义注解@Annotation注解表达式}

现在由于spring优化我们可以直接导入一个依赖就可以了。

面试题:SpringAop原理: 

代理模式:

模式:适配器门面代理,单例工厂 

springAop的底层原理就是基于代理模式。

原本是 调用方直接调用,但是这时候调用方先调用代理对象,代理对象调用目标对象。

一个简单的例子:

package com.syx.aop.aspect;

import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Component
@Slf4j
@Aspect
public class MyAspectDemo {
    //切点作用域
    @Around("@annotation(com.syx.aop.config.MyAspect)")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("do before........666");
        Object proceed = joinPoint.proceed();
        log.info("do after..........666");
        return proceed;


    }
}
package com.syx.aop.Controller;

import com.syx.aop.config.MyAspect;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("test")
public class TestController {
    @RequestMapping("doBefore")
    @MyAspect
    public String t1(){
        log.info("这是一个t1");
        return "t1";

    }
}

如果没有代理模式应该是调用下面这个代码,但是实际上是调用上面的代码,然后通过

Object proceed = joinPoint.proceed();

方法来调用上面的方法。 

比如日常租房子,租客要去找中介租房子,中介去找房东要房子,一样的道理。

定义:

为其他对象提供⼀种代理以控制对这个对象的访问. 它的作⽤就是通过提供⼀个代理类, 让我们
在调⽤⽬标⽅法的时候, 不再是直接对⽬标⽅法进⾏调⽤, ⽽是通过代理类间接调⽤。并且希望能够增加一些功能。代理模式可以在不修改被代理对象的基础上, 通过扩展代理类, 进⾏⼀些功能的附加与增强

适用场景:

  1. 无法直接调用目标方法
  2. 目标方法提供功能不够,希望进行功能增强 。

接下来我们讲代理的两种方法,不用掌握代码,了解就行。 

静态代理:

由程序员创建代理类或特定⼯具⾃动⽣成源代码再对其编译, 在程序运⾏前代理类的 .class ⽂件就已经存在了。虽然功能增强,但是代码都是挨个写,有点麻烦。

动态代理:springaop实现了动态代理

  1. Jdk代理:只能代理接口。
  2. CGLIB代理 (实现方式):既可以代理类,也可以代理接口

在程序运行时,运用反射机制动态创建而成。代理对象通过invoke方法调用目标对象的方法。并且在里边进行功能增强。

适配器模式是代码的补偿,而代理模式则是刚开始就设计好的。

spring是基于动态代理实现的,动态代理是基于反射实现的。

既可以代理类,又可以代理接口。

jdk和cglib区别:
  1. jdk可以代理接口不可以代理类,cglib可以代理接口又代理类。
  2.  spring既使用jdk和cglib代理.
代理⼯⼚有⼀个重要的属性: proxyTargetClass, 默认值为false. 也可以通过程序设置。(背诵)。

八股文:spring什么时候使用jdk代理什么时候实现cglib代理。

 spring默认使用jdk代理,默认proxytargetclass是false,如果是接口使用jdk,springboot默认是true,全部使用cglib实现。

面试题:

  1. 什么是aop
  2. springaop实现方式:
  3. 实现原理(jdk,cglib)。
  4. spring使用哪种jdk,cglib,不太一样springboot 和spring
  5. jdk和cglib区别:

举例:我要在某ke上面买一个房子,静态代理就是别墅在挂牌出售的时候就已经准备好代理了,不管是谁想买房子,都是这个代理人已经分配好了,动态代理就是我点击买房的时候才会分配好代理。

反射回顾:

任何一个类都可以知道他的所有属性和方法

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值