Spring5_AOP

尚硅谷课堂笔记:

链接: https://pan.baidu.com/s/1BPdI_vDWW2M-1A0okF3Pww 提取码: 2333
视频的代码笔记和资料。

老师笔记中的某些内容不再赘叙

此笔记 针对以上笔记为基础 添加补充

主要目的为针对自己复习学习

AOP

image-20220315103119533

image-20220315095850559

1.AOP底层原理

底层使用了 动态代理

知识补充: 静态代理,动态代理

代理类和被代理类实现同一个接口

静态代理

  • 代理类 和 被代理类 编译期间已经确定下来啦

    interface ClothFactory{
        void produceCloth();
    }
    //代理类
    class ProxyClothFactory implements ClothFactory{
        private ClothFactory factory;//用被代理类进行实例化
    
        public ProxyClothFactory(ClothFactory factory) {
            this.factory = factory;
        }
    
        @Override
        public void produceCloth() {
            System.out.println("代理工厂准备工作代码");
            factory.produceCloth();
            System.out.println("代理工厂后续结尾代码");
        }
    }
    //被代理类对象
    class NikeClothFactory implements ClothFactory{
    
        @Override
        public void produceCloth() {
            System.out.println("Nike工厂生产衣服");
        }
    }
    public class StaticProxyTest {
        public static void main(String[] args) {
            NikeClothFactory nikeCloth = new NikeClothFactory();
            ProxyClothFactory proxyClothFactory = new ProxyClothFactory(nikeCloth);
            proxyClothFactory.produceCloth();
            //代理工厂准备工作代码
            //Nike工厂生产衣服
            //代理工厂后续结尾代码
        }
    }
    

    动态代理

    image-20220315170604584

interface  Human{
    String getBelief();
    void eat(String food);
}
//被代理类
class SuperMan implements Human{

    @Override
    public String getBelief() {
        return "I believe I can fly!";
    }

    @Override
    public void eat(String food) {
        System.out.println("我喜欢吃"+food);
    }
}

class proxyFactory{
    // obj 就是创建的被代理的对象
    //调用这个方法解决问题1
    public static Object getProxyInstance(Object obj){
        MyInvocationHandler handler = new MyInvocationHandler();
        handler.bind(obj);
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),handler);
    }
}
//匿名内部类也可以
class MyInvocationHandler implements InvocationHandler{
    private Object obj;//需要使用被代理类的对象进行赋值

    public void bind(Object obj){
        this.obj =obj;
    }
    //当我们通过代理类的对象,调用方法a时,就会自动的调用如下的方法: invoke()
    //里面已经封装好了 比如调eat方法时 会调用下面这个invoke方法
    //这步很关键,那个参数是接口,接口无法实例化,通过它的实现类来实例化,实现类的对象“替代”了这个参数,多态的思想
    /**
     *
     * @param proxy 就是上面那个getProxyInstance返回的对象
     * @param method 代理类调的哪个方法 就是哪个方法(应该是被代理类的方法)
     * @param args
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //method:即为代理类对象调用的方法,此方法也就作为了被代理类对象要调用的方法
        Object returnValue = method.invoke(obj, args);
        //上述方法的返回值
        return returnValue;
    }
}

public class ProxyTest {
    public static void main(String[] args) {
        SuperMan superMan = new SuperMan();
        Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan);
        System.out.println(proxyInstance.getBelief());
        proxyInstance.eat("麻辣烫");
        System.out.println("-------------------------");
		//动态性
        ClothFactory proxyInstance1 = (ClothFactory) ProxyFactory.getProxyInstance(new NikeClothFactory());
        proxyInstance1.produceCloth();

    }
}

image-20220315175717274

image

知识补充完毕

image-20220315111053965

有接口的情况

image-20220315201952897

image-20220315203922864

代码参考上面知识补充的即可

你调的是什么方法 就会增强什么方法

没有接口的情况

原始方法,利用子类继承发展功能

image-20220315202836857

image-20220315203120575

2.AOP操作的术语

  • 连接点:可以被增强的方法;
  • 切入点:实际被增强的方法
  • 通知:增强的功能
  • 切面: 是一个动作

image-20220315212925448

3.AOP操作—准备

image-20220315213829611

image-20220315213922831

AOP相关依赖:

image-20220315214525279

maven : spring-boot-starter-aop

4.切入点表达式

image-20220315220511902

image-20220315220801264

image-20220315221245882

语法结构链接点击

修饰符可以以省略,返回值不能省

*代表 任意返回类型

5.注解操作

image-20220316093625566

image-20220316094114709

image-20220316164727805

对应的注解 在配置类上写 @EnableAspectJAutoProxy

@Configuration //当前类作为配置类
@ComponentScan(basePackages = {"com.company"})
//@EnableAspectJAutoProxy注解等同于在xml中配置aspectj-autoproxy,表示开启spring对注解AOP的支持
//ture表示使用cglib代理 默认false表示用jdk代理 没接口应该使用cglib但是我的类测试false也行 可能高版本自己选择了
@EnableAspectJAutoProxy(proxyTargetClass = true) 
public class SpringConfig {

}

image-20220316094846288

@Component
@Aspect
@EnableAspectJAutoProxy
public class UserProxy {

    @Before(value = "execution(* com.company.Spring5.AOP.Anno.User.add(..))")
    public void before(){
        System.out.println("Before...");
    }
    // 最终通知 不管有没有异常
    @After("execution(* com.company.Spring5.AOP.Anno.User.add(..))")
    public void after(){
        System.out.println("After...");
    }
    //返回通知(后置通知)  afterreturning只有正常返回才会执行, 发生异常不执行
    @AfterReturning("execution(* com.company.Spring5.AOP.Anno.User.add(..))")
    public void afterReturning(){
        System.out.println("afterReturning...");
    }
    //异常通知 发生异常后执行
    @AfterThrowing("execution(* com.company.Spring5.AOP.Anno.User.add(..))")
    public void afterThrowing(){
        System.out.println("AfterThrowing...");
    }
    //环绕通知
    @Around("execution(* com.company.Spring5.AOP.Anno.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        System.out.println("Around前...");
        proceedingJoinPoint.proceed();
        //发生异常后不执行  Around后
        System.out.println("Around后...");
    }
}
//被增强的类
@Component
public class User {
    public void add(){

        System.out.println("add...");
    }

}

Around前…
Before…
add…
Around后…
After…
afterReturning…

这里方法里面的…代表适配所有方法,实际上参数是用来区分重载方法的

6.公共切入点提取

//相同切入点抽取
@Pointcut(value = "execution(* com.company.Spring5.AOP.Anno.User.add(..))")
public  void pointDemo() {

}

@Before(value = "pointDemo")
public void before(){
    System.out.println("Before...");
}

7.多个增强类对同一个类进行了增强 设置优先级

image-20220316164349203

0开始

Before 永远在After前面

8.xml操作(了解)

image-20220317202039473

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值