SpringAOP入门-面向切面编程

先解释一下到底什么是AOP吧。

SpringAOP入门-面向切面编程_第1张图片

如图,系统中有若干个模块,每个模块对应某功能,而还有些特定的功能是每个模块几乎都会用到的,比如日志这种,想要降低日志模块和每个模块的耦合,那么AOP就是必须的了。在这里,所谓的Aspect(切面)就是日志模块,而其他模块就是被切的。

AOP:面向切面编程

  • 切面:系统里面一个特定的模块,贯穿整个系统。比如日志。

  • 配置方式:java注解或者用xml配置。

  • 利用JAVA注解实现AOP

    1、配置Spring依赖(Spring版本最好选择4.0.0到5.0.0之间)

    
    
    org.springframework
    spring-core
    4.3.7.RELEASE
    
    
    org.springframework
    spring-context
    4.3.7.RELEASE
    
    
    org.springframework
    spring-aop
    4.3.7.RELEASE
    
    
    org.aspectj
    aspectjweaver
    1.8.9
    

    2、创建(生成)Spring配置文件

    如果用的是IntelliJ IDEA,可以快捷生成spring的配置文件,方法如下:

    右键项目名-->NEW-->XML Configuration File-->Spring Config

    生成了Spring配置文件后,添加关于AOP的文件头:

    
    
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd">

    添加自动代理:

    
    

    创建三个类,分别是:

    1、将被切入的类,也就是普通的Service

    
    public class CustomerService {
        private String name;
        private String url;
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public void printName() {
            System.out.println("Customer name : " + this.name);
        }
    
        public void printURL() {
            System.out.println("Customer website : " + this.url);
        }
    
        public void printThrowException() {
            throw new IllegalArgumentException();
        }
    }

    2、切面类,用于切入

    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    
    @Aspect
    public class MyAspect {
        @Pointcut("execution(* cn.jdfo.CustomerService.printName())")
        public void pointCut(){}
    
        @Before("pointCut()")
        public void logBefore(){
            System.out.println("before");
        }
    }

    切面类用了aspectj的注解,还有After、AfterRunning、AfterReturning、Around这些。

    Pointcut是一个切入点,上面的logBefore方法就是在printName方法结束之前执行。

    3、程序入口

    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class App {
        public static void main(String[] args) {
            ApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] { "spring.xml" });
            CustomerService cust = (CustomerService) appContext.getBean("customerService");
            System.out.println("*************************");
            cust.printName();
            System.out.println("*************************");
            cust.printURL();
            System.out.println("*************************");
            try {
                cust.printThrowException();
            } catch (Exception ignored) {
            }
        }
    }

    这个程序在JAVA8中运行正常,但是在JAVA9运行会出现错误:

    
    java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut pointCut

    还不清楚发生这个错误的原因。

    另:ApplicationContext可以通过多种方式获得,这里用的是用于测试的一种,直接生成一个应用环境,而在实际应用中通常通过实现一个接口:ApplicationAware(好像这样的)。详见:

    接下来是通过xml配置实现AOP

    xml配置:

    
    
        
            
            
                
                
            
        

    MySAspect类:

    
    public class MySAspect {
        public void logBefore(){
            System.out.println("before");
        }
        public void logAfter(){
            System.out.println("after");
        }
    }

    这个用JAVA9就没有问题,运行结果如下:

    
    *************************
    before
    Customer name : Jdfohewk
    after
    *************************
    before
    Customer website : http://www.baidu.com
    after
    *************************
    before
    after

    两种方法相比较,Spring AOP兼容性更好,而AspectJ暂时还不能很好地支持JAVA9,代码复杂程度二者差不多。所以我选择用Spring AOP...

你可能感兴趣的:(JAVA)