• Spring AOP快速使用教程


    ​ Spring是方法级别的AOP框架,我们主要也是以某个类的某个方法作为连接点,用动态代理的理论来说,就是要拦截哪个方法织入对应的AOP通知。为了更方便的测试我们首先创建一个接口

    public interface RoleService {
        public void printRole(Role role);
    }
    

    然后创建一个实现类

    @Component
    public class RoleServiceImpl implements RoleService {
        public void printRole(Role role) {
            System.out.println(role.toString());
        }
    }
    

    ​ 这个类没啥特别,这个时候把printRole作为AOP的连接点,那么用动态代理的语言就是要为类RoleServiceImpl生成代理对象,然后拦截printRole方法,可以用于产生各种AOP通知方法。

    ​ 接着我们来进行切面的创建,他如同一个拦截器,在Spring中只要使用@Aspect注解一个类,那么Spring IOC 容器就会认为这是一个切面了。

    @Aspect
    public class RoleAspect {
    
        //在被代理对象的方法前调用 ,使用args来传递参数
        @Before("execution(* com.aop.RoleServiceImpl.printRole(..)) && args(role,sort)")
        public void before(Role role, int sort) {
            System.out.println("before...");
        }
    
        //在被代理对象的方法后调用
        @After("execution(* com.aop.RoleServiceImpl.printRole(..))")
        public void after() {
            System.out.println("after...");
        }
    
        //在被代理对象方法正常返回后调用
        @AfterReturning("execution(* com.aop.RoleServiceImpl.printRole(..))")
        public void afterRunning() {
            System.out.println("afterRunning");
        }
    
        //在被代理对象方法抛出异常后使用
        @AfterThrowing("execution(* com.aop.RoleServiceImpl.printRole(..))")
        public void afterThrowing() {
            System.out.println("afterThrowing");
        }
    
        //将验证角色对象是否为空的类加入到切面中
        //value=""表示对某类进行增强,defaultImpl表示默认的实现类
        @DeclareParents(value = "com.aop.RoleServiceImpl+", defaultImpl = RoleVerifierImpl.class)
        public RoleVerifier roleVerifier;
    }
    

    ​ 此时连接点和切面我们都创建完成了,这个时候可以编写代码来测试AOP的内容,首先要对Spring的Bean进行配置,采用注解Java配置。

    @Configuration
    @EnableAspectJAutoProxy
    @ComponentScan("com")
    public class AppConfig {
        @Bean
        public RoleAspect getRoleAspect() {
            return new RoleAspect();
        }
    }
    

    测试AOP流程

    public class Main {
        public static void main(String[] args) {
            ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
            RoleService roleService = (RoleService) ctx.getBean(RoleService.class);
            //使用刚才创建的RoleVerifier来进行检测role对象是否为空
            RoleVerifier verifier = (RoleVerifier) ctx.getBean(RoleVerifier.class);
    
            Role role = new Role();
            role.setId(1L);
            role.setRoleName("张三");
            role.setRoleNote("张三的备注信息");
            System.out.println("##测试结果");
            roleService.printRole(role);
            System.out.println("#####################");
            //测试异常通知
            role = null;
            roleService.printRole(role, 2);
        }
    }
    
    ##测试结果
    before...
    Role{id=1, roleName='张三', roleNote='张三的备注信息'}
    1
    afterRunning
    after...
    #####################
    before...
    afterThrowing  ##异常通知
    after...
    Exception in thread "main" java.lang.NullPointerException
    	at com.aop.RoleServiceImpl.printRole(RoleServiceImpl.java:9)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    

    很显然切面的通知已经通过AOP织入约定的流程当中了,这时我们可以使用AOP来处理一些需要切面的场景了。

  • 相关阅读:
    Dubbo基本结构及执行流程
    用户体验新尝试&思考|让“跳转”加速
    latex,横线除号
    三十九、jQuery
    B/S医院HIS绩效考核系统源码
    五.Dockerfile文件编写的常用指令记录解释
    体系结构28_多处理机(2)
    docker registry web ui 及私有镜像仓库 安装配置记录
    Cpolar+Inis结合在Ubuntu上打造出色的博客网站,快速上线公网访问
    java对接支付宝支付
  • 原文地址:https://www.cnblogs.com/MineLSG/p/16349882.html