spring中AOP(面向切面编程)

本文深入探讨了Spring中的AOP(面向切面编程),包括其与IOC-DI的区别、动态代理机制、AOP的专业术语、通知类型、切入点表达式及其在实际场景中的应用。通过案例展示了JDK和CGLIB动态代理的实现,并介绍了Spring的默认代理策略。此外,还提供了AOP的实战练习,以帮助读者更好地掌握这一重要技术。
摘要由CSDN通过智能技术生成

spring中AOP(面向切面编程)

面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是spring框架中的一个重要内容,是函数式编程中的一种衍生范程.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率.

AOP主要作用:在不修改原有代码的条件下,对方法进行扩展

IOC-DI和AOP之间的区别:

  1. IOC-DI:利用第三方容器将对象统一管理.利用依赖注入为属性赋值,解决了对象与对象之间的耦合性的问题.(解决对象间的耦合问题)
    升华:springMVC框架(对象)/Mybatis框架(对象)类似的框架都可以交给spring容器管理.spring可以以一种统一的方式管理其它第三方的框架,使得调用浑然一体,耦合低,解决了框架和框架之间耦合性问题.
  2. AOP 名称为面向切面编程,使得业务逻辑各部分之间的耦合度降低(解决业务逻辑间的耦合问题)

动态代理

动态代理作用:

使用代理机制,可以有效降低代码的耦合性,将公共的代码/重复的代码,写到代理机制中,通过代理机制调用目标方法,使得真实的业务被调用,通过代理机制,可以有效的降低业务的耦合性.

代理的特点:
使用代理的对象和使用目标的对象看起来是一模一样的

动态代理分类(重点)

动态代理-JDK动态代理
  1. JDK动态代理是JDK源码提供的,无需导入额外的jar包

  2. JDK动态代理对象要求实现和被代理者相同的接口(代理对象和目标对象拥有相同数等且相同的方法,保证用户使用体验一样)—必须有接口

  3. JDK动态代理创建速度快,运行时稍慢

创建代理对象工具API
  1. 动态代理创建代理对象的API Proxy.newProxyInstance(loader,interfaces,h)

  2. 动态代理的参数几个/分别是谁 1.类加载器 2.接口数组 3.InvocationHandler处理器

  3. 代理对象调用方法时,为了扩展方法内容,调用处理器方法~~~

JDK动态代理示例:

1.定义业务类
业务接口

package com.jt.demo1.service;

public interface UserService {
   
    void addUser();
}

业务类:

package com.jt.demo1.service;

import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
   
    @Override
    public void addUser() {
   
        System.out.println("新增用户成功!!!");
    }
}

2.JDK动态代理

//当前类是工具API,目的获取代理对象
public class JDKProxy {
   

    /**
     * public static Object newProxyInstance(ClassLoader loader,
     *                                           Class<?>[] interfaces,
     *                                           InvocationHandler h)
     * newProxyInstance方法参数说明:
     * ClassLoader loader,类加载器,将class加载到java运行机制中
     * Class<?>[] interfaces,被代理者的接口数组,java可以多实现接口
     * InvocationHandler h,将代理对象扩展的内容写到处理器中
     */
    public static Object getProxy(Object target){
   
        //1.获取目标对象的类加载器
        ClassLoader loader = target.getClass().getClassLoader();
        //2.获取接口数组
        Class<?>[] interfaces = target.getClass().getInterfaces();
        //创建代理对象
        /*
        InvocationHandler headler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("事务开始");
                //调用  让目标方法执行  target:目标对象!!!其它的固定写法
                Object result = method.invoke(target, args);//让目标方法执行
                System.out.println("事务结束");
                return result;
            }
        };
        return Proxy.newProxyInstance(loader, interfaces,headler);
        */
        
        
        return Proxy.newProxyInstance(loader, interfaces, new InvocationHandler() {
   
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   
                System.out.println("事务开始");
                //调用  让目标方法执行  target:目标对象!!!其它的固定写法
                Object result = method.invoke(target, args);//让目标方法执行
                System.out.println("事务结束");
                return result;
            }
        });
    }

    /*
    //获取InvocationHandler对象
    public InvocationHandler getInvocationHandler(Object target){
        //当代理执行业务操作时,通过InvocationHandler进行业务的扩展
        return new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("事务开始");
                //调用  让目标方法执行  target:目标对象!!!其它的固定写法
                Object result = method.invoke(target, args);//让目标方法执行
                System.out.println("事务结束");
                return result;
            }
        };
    }
     */

}

3.配置类

package com.jt.demo1.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.jt.demo1")
public class SpringConfig {
   
}

4.测试类

public class TestTX {
   
    public static void main(String[] args) {
   
        //创建容器
        ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfig.class);
        
        //1.获取目标对象
        UserService target = app.getBean(UserService.class);
        
        //2.获取代理对象,JDK动态代理和目标对象必须实现同一接口,保持一模一样
        UserService proxy = (UserService) JDKProxy.getProxy(target);
        
        proxy.addUser();
    }
}
CGLIB动态代理示例:

1.CGLIB动态代理需要导入额外的jar包,才能使用

2.CGLIB被代理者有没有接口都可以,但是CGLIB代理对象是目标对象的子类(继承)

3.CGLIB动态代理创建速度慢,运行时快

关于动态代理总结:

为什么使用动态代理:实现了业务层的解耦

规则:将公共的代码/重复的代码,写到代理对象中,业务层只专注于自己的业务即可~~

AOP介绍

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

总结: Spring中的AOP 利用代理对象在不修改源代码的条件下,对方法进行扩展.

AOP专业术语

1).连接点: 用户可以被扩展的方法
2).切入点: 用户实际扩展的方法
3).通知: 扩展方法的具体实现
4).切面: 将通知应用到切入点的过程

AOP面向切面编程入门案例

1.引入aop的jar包,配置pom.xml文件,让maven导包

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2.定义service层的接口和实现类
接口:

package com.jt.demo2.service;

public interface UserService {
   
    void addUser();
}

接口的实现类:

package com.jt.demo2.service;
import <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值