栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Spring】基于注解的AOP编程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Spring】基于注解的AOP编程

一、开发步骤

1 原始功能

public interface UserService {
    void register(User user);
    boolean login(String name, String password);
}
public class UserServiceImpl implements UserService {
    @Override
    public void register(User user) {
        System.out.println("UserServiceImpl.register 业务运算 + DAO");
        // throw new RuntimeException("测试异常");
    }

    @Log
    @Override
    public boolean login(String name, String password) {
        System.out.println("UserServiceImpl.login 业务运算 + DAO");
        return true;
    }
}

2 额外功能
3 切入点
4 组装切面

2、3、4都放在MyAspect内完成。

@Aspect
public class MyAspect {
    @Around("execution(* login(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("---- aspect log ----");
        Object ret = joinPoint.proceed();
        return ret;
    }
}


    
    
    
    
    

二、切入点复用

切入点复用:在切面类中定义⼀个函数,上面用 @Pointcut 注解。
通过这种方式定义切入点表达式,后续更加有利于切入点复用。

@Aspect
public class MyAspect {

    @Pointcut("execution(* login(..))")
    public void myPoincut() {}

    @Around(value = "myPoincut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("---- aspect log ----");
        Object ret = joinPoint.proceed();
        return ret;
    }
    @Around(value = "myPoincut()")
    public Object around1(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("---- aspect transaction ----");
        Object ret = joinPoint.proceed();
        return ret;
    }
}
三、切换动态代理创建方式

AOP 底层实现 2 种代理创建方式:

  • JDK:通过 实现接口,做新的实现类 创建代理对象
  • Cglib:通过 继承父类,做新的子类 创建代理对象

默认情况 AOP 编程 底层应用 JDK动态代理创建方式。

基于注解的 AOP 开发 中切换为 Cglib:


传统的 AOP 开发 中切换为 Cglib:


	...

四、业务方法互相调用

在同⼀个业务类中,进⾏业务方法间的相互调用,只有最外层的方法,才是加入了额外功能(内部的方法,通过普通的方式调用,都调用的是原始方法)。如果想让内层的方法也调用代理对象的方法,就要实现 AppicationContextAware 获得⼯厂,进而获得代理对象。

public class UserServiceImpl implements UserService, ApplicationContextAware {
    private ApplicationContext ctx;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ctx = applicationContext;
    }
    @Override
    public void register(User user) {
        System.out.println("UserServiceImpl.register 业务运算 + DAO");

        // this.login("zhenyu", "123456"); // 这么写调用的是本类的 login 方法, 即原始对象的 login 方法
        // 为什么不在这里创建一个工厂获取代理对象呢?
        // Spring的工厂是重量级资源, 一个应用中应该只创建一个工厂.
        // 因此我们必须通过 ApplicationContextAware 拿到已经创建好的工厂
        UserService userService = (UserService) ctx.getBean("userService");
        userService.login("yusael", "123456");
    }

    @Override
    public boolean login(String name, String password) {
        System.out.println("UserServiceImpl.login 业务运算 + DAO");
        return true;
    }
}
五、总结


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/309938.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号