zoukankan      html  css  js  c++  java
  • Spring AOP的两种实现方式(AspectJ注解配置和方法配置)

    AspectJ是一个java实现的AOP框架,它能够对java代码进行AOP编译(一般在编译期进行),让java代码具有AspectJ的AOP功能(当然需要特殊的编译器),可以这样说AspectJ是目前实现AOP框架中最成熟,功能最丰富的语言,更幸运的是,AspectJ与java程序完全兼容,几乎是无缝关联,因此对于有java编程基础的工程师,上手和使用都非常容易。

    Spring AOP 与ApectJ 的目的一致,都是为了统一处理横切业务,但与AspectJ不同的是,Spring AOP 并不尝试提供完整的AOP功能(即使它完全可以实现),Spring AOP 更注重的是与Spring IOC容器的结合,并结合该优势来解决横切业务的问题,因此在AOP的功能完善方面,相对来说AspectJ具有更大的优势,同时,Spring注意到AspectJ在AOP的实现方式上依赖于特殊编译器(ajc编译器),因此Spring很机智回避了这点,转向采用动态代理技术的实现原理来构建Spring AOP的内部机制(动态织入),这是与AspectJ(静态织入)最根本的区别。在AspectJ 1.5后,引入@Aspect形式的注解风格的开发,Spring也非常快地跟进了这种方式,因此Spring 2.0后便使用了与AspectJ一样的注解。请注意,Spring 只是使用了与 AspectJ 5 一样的注解,但仍然没有使用 AspectJ 的编译器,底层依是动态代理技术的实现,因此并不依赖于 AspectJ 的编译器。

    下面是Spring AOP的AspectJ注解式实现:

    自定义注解

    package com.dust.exercises.aop;
    
    import java.lang.annotation.*;
    
    /**
     * Created by zhaohongyang on 2018/8/14.
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Action {
        String customName();
    }

    定义一个被拦截的方法(注解式拦截)

    package com.dust.exercises.aop;
    
    import org.springframework.stereotype.Service;
    
    /**
     * Created by zhaohongyang on 2018/8/14.
     */
    @Service
    public class DemoAnnotationService {
    
        //自定义注解中的自定义方法
        @Action(customName="注解拦截的add操作")
        public void add(){
    
        }
    }

    定义一个被拦截的方法(方法式拦截)

    package com.dust.exercises.aop;
    
    import org.springframework.stereotype.Service;
    
    /**
     * Created by zhaohongyang on 2018/8/14.
     */
    @Service
    public class DemoMethodService {
    
        public void add(){
    
        }
    }

    定义切面的类

    package com.dust.exercises.aop;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.stereotype.Component;
    
    import java.lang.reflect.Method;
    
    /**
     * Created by zhaohongyang on 2018/8/14.
     */
    @Aspect
    @Component
    public class LogAspect {
    
        @Pointcut("@annotation(com.dust.exercises.aop.Action)")
        public void annotationPointCut() {
        }
    
        @After("annotationPointCut()")
        public void after(JoinPoint joinPoint) {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            Action action = method.getAnnotation(Action.class);
            System.out.println("注解式拦截," + action.customName());
        }
    
        @Before("execution(* com.dust.exercises.aop.DemoMethodService.*(..))")
        public void before(JoinPoint joinPoint) {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            System.out.println("方法规则式拦截," + method.getName());
        }
    
    }

    配置类,使用@EnableAspectJAutoProxy 注解开启Spring 对AspectJ 代理的支持。

    package com.dust.exercises.aop;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    
    /**
     * Created by zhaohongyang on 2018/8/14.
     */
    @Configuration
    @ComponentScan("com.dust.exercises.aop")
    @EnableAspectJAutoProxy
    public class AopConfig {
    }

    运行

    package com.dust.exercises.aop;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /**
     * Created by zhaohongyang on 2018/8/14.
     */
    public class Main {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AopConfig.class);
            DemoMethodService demoMethodService = annotationConfigApplicationContext.getBean(DemoMethodService.class);
            DemoAnnotationService demoAnnotationService = annotationConfigApplicationContext.getBean(DemoAnnotationService.class);
            demoMethodService.add();
            demoAnnotationService.add();
            annotationConfigApplicationContext.close();
        }
    }

    结果

  • 相关阅读:
    SQL Server 跨服务器 存储过程传字符串数组不同数据库之间复制表的数据
    SQL Server 跨服务器 存储过程不同数据库之间复制表的数据
    SQL Server 跨服务器 存储过程不同数据库之间复制表的数据
    SQL Server跨服务器查询
    抓包自定义过滤器需加%XXXX%,如%third_play%
    svn 清理命令失败
    通过windug判断某个模块导致程序不能退出。
    如果判断不出是不是某个模块出的问题,删除此模块测试。
    读配置前把vector清掉
    DNS服务器的原理
  • 原文地址:https://www.cnblogs.com/dustcode/p/9483768.html
Copyright © 2011-2022 走看看