Spring注解驱动AOP开发入门

Spring注解驱动AOP开发入门

1. AOP思想

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

2. 实现原理

基于动态代理技术实现。
动态代理技术:
	特点:字节码随用随创建,随用随加载
	分类:基于接口的动态代理,基于子类的动态代理
	作用:不修改源码的基础上对方法增强
  1.基于接口的动态代理
  	提供者:JDK官方
  	使用要求:被代理类最少实现一个接口
  	涉及的类:Proxy
  	创建代理对象的方法:newProxyInstance
  	方法参数:
  		ClassLoader:类加载器,加载代理对象的字节码
  		Class[]:字节码数组,给代理对象提供方法
  			被代理类为普通类:被代理对象.getClass().getInterfaces()
  			被代理类为接口:new Class[]{被代理对象.class}
  		InvocationHanlder:要增强的方法。为一个接口,需提供实现类(通常为匿名内部类)
  2.基于子类的动态代理
  	提供者:第三方cglib包,需先导入maven坐标
  	使用要求:被代理类不能为最终类,不能被final修饰
  	涉及的类:Enhancer
  	创建代理对象的方法:create
  	方法的参数:
  		Class:字节码。被代理对象的字节码。可创建子类及获取类加载器
  		Callback:增强的代码。通常写一个接口的实现类或匿名内部类
  			Callback中美誉任何方法,通常使用它的子接口MethodInterceptor

3. Spring中AOP的术语

Joinpoint(连接点):所谓连接点是指被拦截到的点。spring只支持方法类型的连接点
Pointcut(切入点):指我们要进行拦截的Joinpoint
Advice(通知/增强):拦截到Joinpoint要做的事,分为前置,后置,异常,最终,环绕通知
Introduction(引介):引介是一种特殊的通知,在不修改类代码前提下在运行期动态添加一些方法
Target(目标对象):代理的目标对象
Weaving(织入):把增强应用到目标对象来创建新的代理对象的过程
Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类
Aspect(切面):切入点与通知(引介)的结合

4. 入门案例

4.1 案例介绍

需求: 实现在执行service方法时输出执行日志

4.2 案例实现

4.2.1 业务层接口
/**
* @author 刘淳
*/
public interface UserService {
    /**
    * 保存用户
    */
    void save(User user);
}
4.2.2 业务层实现类
/**
* 用户的业务层实现类
* @author 刘淳
*/
@Service("userService")
public class UserServiceImpl implements UserService{
    @Override
    public void save(User user) {
        System.out.println("保存了:"+user);
    }
}
4.2.3 日志工具类
/**
* 记录日志的工具类
* @author 黑马程序员
* @Company http://www.itheima.com
*/
@Component
@Aspect
public class LogUtil {
    /**
     * 通用切入点表达式
     */
    @Pointcut("execution(* com.itheima.service.impl.*.*(..))")
    private void pt1(){}
    /**
     * 前置通知
     */
    @Before("pt1()")
    public void beforeLog(){
        System.out.println("执行切入点方法前记录日志");
    }
    /**
     * 后置通知
     */
    @AfterReturning("pt1()")
    public void afterReturningLog(){
        System.out.println("正常执行切入点方法后记录日志");
    }
    /**
     * 异常通知
     */
    @AfterThrowing("pt1()")
    public void afterThrowingLog(){
        System.out.println("执行切入点方法产生异常后记录日志");
    }
    /**
     * 最终通知
     */
    @After("pt1()")
    public void afterLog(){
    	System.out.println("无论切入点方法执行是否有异常都记录日志");
    }
    /**
    * 环绕通知
    */
    @Around("pt1()")
    public Object arountPrintLog(ProceedingJoinPoint pjp){
        //1.定义返回值
        Object rtValue = null;
        try{
            //前置通知
            System.out.println("执行切入点方法前记录日志");
            //2.获取方法执行所需的参数
            Object[] args = pjp.getArgs();
            //3.执行切入点方法
            rtValue = pjp.proceed(args);
            //后置通知
            System.out.println("正常执行切入点方法后记录日志");
            }catch (Throwable t){
            //异常通知
            System.out.println("执行切入点方法产生异常后记录日志");
        }finally {
            //最终通知
            System.out.println("无论切入点方法执行是否有异常都记录日志");
        }
        return rtValue;
    }
}
4.2.4 配置类
/**
* @author 刘淳
*/
@Configuration
@ComponentScan("com.itheima")
@EnableAspectJAutoProxy
public class SpringConfiguration {
}
4.2.5 测试类
/**
* spring的aop环境准备
* @author 刘淳
*/
public class SpringAOPTest {
    public static void main(String[] args) {
        //1.获取容器
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        //2.获取bean对象
        UserService userService = ac.getBean("userService",UserService.class);
        //3.准备数据
        User user = new User();
        user.setId("1");
        user.setUsername("test");
        user.setNickname("泰斯特");
        //4.执行方法
        userService.save(user);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@未安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值