• AOP AspectJ注解


    概念:

    切面(aspect):用来切插业务方法的类。
    连接点(joinpoint):是切面类和业务类的连接点,其实就是封装了业务方法的一些基本属性,作为通知的参数来解析。
    通知(advice):在切面类中,声明对业务方法做额外处理的方法。
    切入点(pointcut):业务类中指定的方法,作为切面切入的点。其实就是指定某个方法作为切面切的地方。
    目标对象(target object):被代理对象。
    AOP代理(aop proxy):代理对象。

    AOP通知类型:
    前置通知(before advice):在切入点之前执行。
    后置通知(after returning advice):在切入点执行完成后,执行通知。
    环绕通知(around advice):包围切入点,调用方法前后完成自定义行为。
    异常通知(after throwing advice):在切入点抛出异常后,执行通知

    依赖包:

        <dependencies>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.3.6.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>1.8.10</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.10</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/cglib/cglib -->
            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>3.2.5</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>4.3.6.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>4.3.6.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>4.3.6.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>4.3.6.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>4.3.6.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/log4j/log4j -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
        </dependencies>
    View Code

    Code:

    package com.qhong;
    
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.stereotype.Component;
    
    public class Main {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            Person person=(Person)context.getBean("babyPerson");
            person.eatBreakfast();
            System.out.println("===================================================");
            person.eatLunch();
            System.out.println("===================================================");
            person.eatSupper();
            System.out.println("===================================================");
            person.drink("可乐");
            System.out.println("===================================================");
       }
    }
    
    interface Person {
        public void eatBreakfast();
        public void eatLunch();
        public void eatSupper();
        public String drink(String name);
    }
    
    @Component
    class BabyPerson implements Person{
    
        @Override
        public void eatBreakfast() {
            System.out.println("小Baby正在吃早餐");
        }
    
        @Override
        public void eatLunch() {
            System.out.println("小Baby正在吃午餐");
        }
    
        @Override
        public void eatSupper() {
            System.out.println("小Baby正在吃晚餐");
        }
    
        @Override
        public String drink(String name) {
            return "小Baby在喝:"+name;
        }
    }
    
    @Component
    @Aspect
    class AdivceMethod {
    
        @Before("execution(* com.qhong.BabyPerson.*(..))")
        // 匹配BabyPerson类所有的方法,注意*和com之间有个空格
        public void beforeEat() {
            System.out
                    .println("-------------------这里是前置增强,吃饭之前先洗小手!--------------------");
        }
    
        @After("execution(* eatLunch(..))")
        // 匹配该工程下所有的eatLunch方法
        public void afterEat() {
            System.out
                    .println("-------------------这里是后置增强,午饭吃完要睡午觉!--------------------");
        }
    
        @Around("execution(* com.qhong.BabyPerson.eatSupper())")
        // 匹配该工程下BabyPerson的eatLunch方法
        public Object aroundEat(ProceedingJoinPoint pjp) throws Throwable {
            System.out
                    .println("-------------------这里是环绕增强,吃晚饭前先玩一玩!-------------------");
            Object retVal = pjp.proceed();
            System.out
                    .println("-------------------这里是环绕增强,晚饭吃完后要得睡觉了!-------------------");
            return retVal;
        }
        @AfterReturning(returning="rvt",pointcut="execution(* com.qhong.BabyPerson.drink(..))")
        public void log(Object rvt) {
            System.out
                    .println("-------------------这里是AfterReturning增强-------------------");
            System.out.println("获取小Baby正在喝的饮料"+rvt);
            System.out.println("记录每天喝的饮料容量");
    
        }
    }

    beans.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="
               http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
               http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
        <!-- 指定自动搜索bean组件、自动搜索切面类 -->
        <context:component-scan base-package="com.qhong"/>
        <!-- 启动@AspectJ支持 -->
        <!-- proxy-target-class默认"false",更改为"ture"使用CGLib动态代理 -->
        <aop:aspectj-autoproxy proxy-target-class="true"/>
    </beans>
    Result:
    -------------------这里是前置增强,吃饭之前先洗小手!--------------------
    小Baby正在吃早餐
    ===================================================
    -------------------这里是前置增强,吃饭之前先洗小手!--------------------
    小Baby正在吃午餐
    -------------------这里是后置增强,午饭吃完要睡午觉!--------------------
    ===================================================
    -------------------这里是环绕增强,吃晚饭前先玩一玩!-------------------
    -------------------这里是前置增强,吃饭之前先洗小手!--------------------
    小Baby正在吃晚餐
    -------------------这里是环绕增强,晚饭吃完后要得睡觉了!-------------------
    ===================================================
    -------------------这里是前置增强,吃饭之前先洗小手!--------------------
    -------------------这里是AfterReturning增强-------------------
    获取小Baby正在喝的饮料小Baby在喝:可乐
    记录每天喝的饮料容量
    ===================================================


    Spring + AspectJ(基于注解:通过 AspectJ execution 表达式拦截方法)
    package com.qhong;
    
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.stereotype.Component;
    
    public class Main {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
            com.qhong.Greeting greeting = (com.qhong.Greeting) context.getBean("greetingImpl");
            greeting.sayHello("Jack");
        }
    }
    
    interface Greeting {
        void sayHello(String name);
    }
    
    @Component
    class GreetingImpl implements Greeting {
        @Override
        public void sayHello(String name) {
            System.out.println("Hello! " + name);
        }
    }
    
    @Aspect
    @Component
    class GreetingAspect {
        @Around("execution(* com.qhong.GreetingImpl.*(..))")
        public Object around(ProceedingJoinPoint pjp) throws Throwable {
            before();
            Object result = pjp.proceed();
            after();
            return result;
        }
    
        private void before() {
            System.out.println("Before");
        }
    
        private void after() {
            System.out.println("After");
        }
    }

    spring.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           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/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <context:component-scan base-package="com.qhong"/>
    
        <aop:aspectj-autoproxy proxy-target-class="true"/>
    </beans>

    Result:

    Before
    Hello! Jack
    After

    遇到的bug

    java.lang.NoClassDefFoundError: org/springframework/beans/factory/NoUniqueBeanDefinitionException

    遇到这个问题应该是groupid是org.springframework的各个依赖之间版本相差太大造成的问题,全都改成统一的就ok了。

    http://tonylit.me/2016/06/29/spring%20aop-AspectJ%E6%B3%A8%E8%A7%A3%E6%96%B9%E5%BC%8F/

    http://www.yiibai.com/spring/spring-aop-aspectj-annotation-example.html

    http://blog.csdn.net/xiaoxian8023/article/details/17285809

    http://www.kancloud.cn/evankaka/springlearning/119670

    http://git.oschina.net/lujianing/aop_demo

    https://my.oschina.net/huangyong/blog/159788

    https://my.oschina.net/huangyong/blog/161338

    https://my.oschina.net/huangyong/blog/161402

    https://my.oschina.net/huangyong/blog/160769

    https://my.oschina.net/huangyong/blog/170494

  • 相关阅读:
    c语言一道题
    try,catch,finally尝试(一个程序块多个catch)
    利用接口及抽象类设计实现
    设计一个限制子类的访问的抽象类实例,要求在控制台输出如下结果
    多态,重写和重载
    织梦被挂了黑链的可能原因和排查清除办法
    织梦cms手机站首页不更新的解决办法
    dedecms织梦会员登录二级域名跨域不能获取数据的解决办法
    织梦cms添加新变量出现:Request var not allow!的解决办法
    织梦dedecms使用Mysql8.0无法登录后台的解决办法
  • 原文地址:https://www.cnblogs.com/hongdada/p/6512589.html
Copyright © 2020-2023  润新知