【Spring】【AOP】【学习笔记】Spring开学很好学1.1

👴发现尽量控制字数更好1点,这真的不是开摆🤗

厦工为什么不上网课😭😭😭😭😭😭😭

AOP

AOP(Aspect Oriented Programming)面向切面编程,是一种不修改源码的情况下,添加功能的种编程思想,OOP有两个不足:对于没有继承关系类的横向共用性,无法处理,也无法动态增加功能。

目的降低耦合

在这里插入图片描述

1、AOP术语

术语解释
切面(Aspect)由切点和增强组成,在Java代码中对于一个切面类
连接点(JointPoint)程序执行的某个位置,如函数调用、函数执行、构造函数调用、获取或设置遍历、类初始化等
切入点(Pointcut)也就是特定的连接点
增强(Advice)织入到目标连接点的代码,也就是额外功能的代码
织入(Weaving)增强添加到目标连接点的过程
前置(Before)、后置(After)、Around(环绕)织入的方位,可前,可后
代理(Proxy)是实现AOP的主要奇数,在代理类种包含了原始类和增强代码的功能

2、AOP底层原理

动态代理

2.1、使用JDK动态代理

有接口,使用JDK动态代理

Proxy类

newProxyInstance()方法 , 三个参数

  • 类加载
  • 增强方法所在的类,这个类实现的接口,支持多个接口
  • 实现这个接口InvocationHandler ,创建代理对象,写增强的部分
public interface UserDao {
    public int add(int a,int b);
    public String update(String id);
}
public class UserDaoImpl implements UserDao {

    @Override
    public int add(int a, int b) {
        return a + b;
    }

    @Override
    public String update(String id) {
        return id;
    }
}

代理对象

public class UserDaoProxy implements InvocationHandler {
    private Object obj;
    public UserDaoProxy(Object obj){
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("方法执行前..." + method.getName() + "传递的参数..." + Arrays.toString(args));
        // 被增强的方法执行
        Object res = method.invoke(obj,args);
        System.out.println("方法之后执行" + obj);
        return res;
    }
}

测试

public class JDKProxy {
    public static void main(String[] args) {
        Class[] interfaces = {UserDao.class};
        UserDaoImpl userDao = new UserDaoImpl();
        UserDao dao =
            (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(),interfaces,new UserDaoProxy(userDao));
    }
}
方法执行前...add传递的参数...[1, 2]
方法之后执行com.flzj.dao.UserDaoImpl@2b193f2d
3

2.2、没接口,使用CGLIB动态代理

创建子类代理对象,增强父类方法

class A extends B{
    public void add(){
        super.add();	// 调用父类的B
        // 增强逻辑
    }
}

3、基于AspectJ的AOP

AspectJ 不是Spring组成部分,独立AOP框架,一般把 AspectJ 和 Spring 框架一起使用AOP操作

3.1、注解方式

切入点表达式

execution([权限修饰符][返回类型][类全路径][方法名称]([参数列表]))

注解作用
@Before前置通知
@AfterReturning后置通知(返回通知)
@After最终通知
@AfterThrowing异常通知
@Around环绕通知
@Pointcut(value)相同切入点的抽取
@Order(数字类型值)设置优先级(对类使用),数值越小越优先
@Before(value = "execution(* com.flzj.proxy.User.add(..))")
public void before(){
    System.out.println("before........");
}
@AfterReturning(value = "execution(* com.flzj.proxy.User.add(..))")
public void afterReturn(){
    System.out.println("afterReturn...");
}
@After(value = "execution(* com.flzj.proxy.User.add(..))")
public void after(){
    System.out.println("after.......");
}
@AfterThrowing(value = "execution(* com.flzj.proxy.User.add(..))")
public void afterThrowing(){
    System.out.println("afterThrowing....");
}
@Around(value = "execution(* com.flzj.proxy.User.add(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    System.out.println("环绕之前");
    proceedingJoinPoint.proceed();
    System.out.println("环绕之后");
}
环绕之前
before........
add........
环绕之后
after.......
afterReturn...

加上bug

int i = 16 / 0;
环绕之前
before........
after.......
afterThrowing....

相同切入点,需要先写一个方法

@Pointcut(value = "execution(* com.flzj.proxy.User.add(..))")
public void pointdemo(){}

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

需要

1、使用aop名称空间 2、开启组件扫描 3、开启Aspect生成代理对象

<!-- 1 -->
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
...
<!-- 2 -->
<context:component-scan base-package="com.flzj.proxy"></context:component-scan>
<!-- 3 开启Aspect生成代理对象 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

3.2、配置方式

<aop:config >标签 配置aop增强

<aop:pointcut >标签 配置切入点 id (给切入点取个名字)和 excution 属性

<aop:aspect >标签 配置切面 ref 属性

<aop:before/after/…>标签 增强作用在具体方法 method 属性 pointcut-ref 属性

<bean id="book" class="com.flzj.bean.Book"></bean>
<bean id="bookProxy" class="com.flzj.bean.BookProxy"></bean>
<aop:config>
    <aop:pointcut id="ppp" expression="execution(* com.flzj.bean.Book.sell(..))"/>
    <aop:aspect ref="bookProxy">
        <aop:before method="proxyMethod" pointcut-ref="ppp"/>
    </aop:aspect>
</aop:config>

🈲 禁止速通,🈲 禁止速通,🈲 禁止速通,🈲 禁止速通🈲 禁止速通,🈲 禁止速通,🈲 禁止速通,🈲 禁止速通🈲 禁止速通,🈲 禁止速通,🈲 禁止速通,🈲 禁止速通

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值