zoukankan      html  css  js  c++  java
  • 基于xml的AOP开发

    1. 开发的步骤

    (1)导入AOP相关坐标

    在pom.xml中

    (2)创建目标接口和目标类(内部有切点)

    (3)创建切面类(内部有增强方法)

    (4)将目标类和切面类的对象创建权交给spring

    (5)在applicationContext.xml中配置织入关系

    (6)测试代码

    案例:

     (1)导入AOP相关坐标,pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.company</groupId>
        <artifactId>spring_aop</artifactId>
        <version>1.0-SNAPSHOT</version>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.2.9.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.9.6</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>5.2.9.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
    
    </project>

    (2)创建目标接口(TargetInterface)和目标类(Target),切点是save()方法

    TargetInterface.java

    package com.company.aop;
    
    public interface TargetInterface {
        void  save();
    }
    

    Target.java

    package com.company.aop;
    
    public class Target implements TargetInterface {
        public void save() {
            System.out.println("save running ...");
        }
    }
    

    (3)创建切面类,增强方法是before()方法

    package com.company.aop;
    
    public class MyAspect {
    
        public void before() {
            System.out.println("前置增强........");
        }
    }
    

    (4)将目标对象和切面对象的创建权交给spring,在applicationContext.xml中配置,Spring的很多功能首要条件就是这些bean要放到容器中,spring才能在容器中拿出对象,进行相应的操作。

     (5)在applicationContext.xml中配置织入关系,method="before"是myAspect的before()方法

    完整版的applicationContext.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: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
    ">
    
        <!--目标对象-->
        <bean id="target" class="com.company.aop.Target"></bean>
        <!--切面对象-->
        <bean id="myAspect" class="com.company.aop.MyAspect"></bean>
        <!--配置织入:告诉spring框架,哪些方法(切点)需要进行哪些增强(前置,后置)-->
        <aop:config>
            <!-- 声明切面-->
            <aop:aspect ref="myAspect">
            <!--切面:切点+通知-->
                <aop:before method="before" pointcut="execution(public void com.company.aop.Target.save())"></aop:before>
            </aop:aspect>
        </aop:config>
    
    </beans>

     (6)测试 ,AopTest.java

    package com.company.test;
    
    import com.company.aop.TargetInterface;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class AopTest {
        @Autowired
        private TargetInterface targetInterface;
        @Test
        public void test1() {
            targetInterface.save();
        }
    
    }
    

      运行结果:

    2. 切点表达式的写法

    <aop:before method="before" pointcut="execution(public void com.company.aop.Target.save())"></aop:before>

    (1)访问修饰符可以省略

    (2)返回值类型、包名、类名、方法名可以使用星号*代表任意

    (3)包名与类名之间一个点.代表当前包下的类,两个点..表示当前包及其子包下的类

    (4)参数列表可以使用两个点..表示任意个数,任意类型的参数列表

    例如:

    excution(public void com.company.aop.Target.method())

    excution(void com.company.aop.Target.*(..))  *表示任意方法,(..)表示参数任意个

    excution(* com.company.aop.*.*(..))  aop包下的任意类,任意方法,这种形式最常用

    excution(* com.company.aop..*.*(..))  aop包及其子包下的任意类,任意方法

    excution(* *..*.*(..))

    上面的可以改成这样

    <aop:before method="before" pointcut="execution(* com.company.aop.*.*(..))"></aop:before>

     3. 通知的类型

     

     

    3.1. 后置通知 

    在原来的切面类中加如后置增强方法

    MyAspect.java

    package com.company.aop;
    
    public class MyAspect {
    
        public void before() {
            System.out.println("前置增强........");
        }
        public void afterReturning() {
            System.out.println("后置增强");
        }
    }
    

      再在applicationContext.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: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
    ">
    
        <!--目标对象-->
        <bean id="target" class="com.company.aop.Target"></bean>
        <!--切面对象-->
        <bean id="myAspect" class="com.company.aop.MyAspect"></bean>
        <!--配置织入:告诉spring框架,哪些方法(切点)需要进行哪些增强(前置,后置)-->
        <aop:config>
            <!-- 声明切面-->
            <aop:aspect ref="myAspect">
            <!--切面:切点+通知-->
                <aop:before method="before" pointcut="execution(* com.company.aop.*.*(..))"></aop:before>
                <aop:after-returning method="afterReturning" pointcut="execution(* com.company.aop.*.*(..))"></aop:after-returning>
            </aop:aspect>
        </aop:config>
    
    </beans>

    执行AopTest.java

    运行结果:

     3.2. 环绕通知

    在原来的切面类中加入环绕通知方法

    MyAspect.java

    package com.company.aop;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    
    public class MyAspect {
    
        public void before() {
            System.out.println("前置增强........");
        }
        public void afterReturning() {
            System.out.println("后置增强");
        }
    
        // ProceedingJoinPoint 正在执行的连接点 === 切点
        public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("环绕前增强.....");
            // 切点方法
            Object proceed = proceedingJoinPoint.proceed();
            System.out.println("环绕后增强.....");
            return proceed;
        }
    
    }
    

      再在applicationContext.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: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
    ">
    
        <!--目标对象-->
        <bean id="target" class="com.company.aop.Target"></bean>
        <!--切面对象-->
        <bean id="myAspect" class="com.company.aop.MyAspect"></bean>
        <!--配置织入:告诉spring框架,哪些方法(切点)需要进行哪些增强(前置,后置)-->
        <aop:config>
            <!-- 声明切面-->
            <aop:aspect ref="myAspect">
            <!--切面:切点+通知-->
    <!--            <aop:before method="before" pointcut="execution(* com.company.aop.*.*(..))"></aop:before>-->
    <!--            <aop:after-returning method="afterReturning" pointcut="execution(* com.company.aop.*.*(..))"></aop:after-returning>-->
                <aop:around method="around" pointcut="execution(* com.company.aop.*.*(..))"></aop:around>
            </aop:aspect>
        </aop:config>
    
    </beans>

    执行AopTest.java

    运行结果:

     3.3 异常抛出通知

    在MyAspect.java中加入异常抛出增强方法

    package com.company.aop;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    
    public class MyAspect {
    
        public void before() {
            System.out.println("前置增强........");
        }
        public void afterReturning() {
            System.out.println("后置增强");
        }
    
        // ProceedingJoinPoint 正在执行的连接点 === 切点
        public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("环绕前增强.....");
            // 切点方法
            Object proceed = proceedingJoinPoint.proceed();
            System.out.println("环绕后增强.....");
            return proceed;
        }
    
        public void afterThrowing() {
            System.out.println("异常抛出增强.....");
        }
    
    }
    

      异常抛出的是目标对象中的异常,因此在Target中构造异常

    Target.java

    package com.company.aop;
    
    public class Target implements TargetInterface {
        public void save() {
            int i = 1/0;
            System.out.println("save running ...");
        }
    }
    

      再在applicationContext.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: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
    ">
    
        <!--目标对象-->
        <bean id="target" class="com.company.aop.Target"></bean>
        <!--切面对象-->
        <bean id="myAspect" class="com.company.aop.MyAspect"></bean>
        <!--配置织入:告诉spring框架,哪些方法(切点)需要进行哪些增强(前置,后置)-->
        <aop:config>
            <!-- 声明切面-->
            <aop:aspect ref="myAspect">
            <!--切面:切点+通知-->
    <!--            <aop:before method="before" pointcut="execution(* com.company.aop.*.*(..))"></aop:before>-->
    <!--            <aop:after-returning method="afterReturning" pointcut="execution(* com.company.aop.*.*(..))"></aop:after-returning>-->
                <aop:around method="around" pointcut="execution(* com.company.aop.*.*(..))"/>
                <aop:after-throwing method="afterThrowing" pointcut="execution(* com.company.aop.*.*(..))"/>
            </aop:aspect>
        </aop:config>
    
    </beans>

    执行AopTest.java

    运行结果:

    3.4 最终通知

    在MyAspect.java中加入最终增强方法

    package com.company.aop;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    
    public class MyAspect {
    
        public void before() {
            System.out.println("前置增强........");
        }
        public void afterReturning() {
            System.out.println("后置增强");
        }
    
        // ProceedingJoinPoint 正在执行的连接点 === 切点
        public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("环绕前增强.....");
            // 切点方法
            Object proceed = proceedingJoinPoint.proceed();
            System.out.println("环绕后增强.....");
            return proceed;
        }
    
        public void afterThrowing() {
            System.out.println("异常抛出增强.....");
        }
    
        public void after() {
            System.out.println("最终增强.....");
        }
    
    }
    

      再在applicationContext.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: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
    ">
    
        <!--目标对象-->
        <bean id="target" class="com.company.aop.Target"></bean>
        <!--切面对象-->
        <bean id="myAspect" class="com.company.aop.MyAspect"></bean>
        <!--配置织入:告诉spring框架,哪些方法(切点)需要进行哪些增强(前置,后置)-->
        <aop:config>
            <!-- 声明切面-->
            <aop:aspect ref="myAspect">
            <!--切面:切点+通知-->
    <!--            <aop:before method="before" pointcut="execution(* com.company.aop.*.*(..))"/>-->
    <!--            <aop:after-returning method="afterReturning" pointcut="execution(* com.company.aop.*.*(..))"/>-->
                <aop:around method="around" pointcut="execution(* com.company.aop.*.*(..))"/>
                <aop:after-throwing method="afterThrowing" pointcut="execution(* com.company.aop.*.*(..))"/>
                <aop:after method="after" pointcut="execution(* com.company.aop.*.*(..))"/>
            </aop:aspect>
        </aop:config>
    
    </beans>

    运行结果:

     4.切点表达式抽取

    当多个增强的切点表达式相同时,可以将切点表达式进行抽取,在增强中使用pointcut-ref属性代替pointcut属性来引用抽取后的切点表达式

    <?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: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
    ">
    
        <!--目标对象-->
        <bean id="target" class="com.company.aop.Target"></bean>
        <!--切面对象-->
        <bean id="myAspect" class="com.company.aop.MyAspect"></bean>
        <!--配置织入:告诉spring框架,哪些方法(切点)需要进行哪些增强(前置,后置)-->
        <aop:config>
            <!-- 声明切面-->
            <aop:aspect ref="myAspect">
                <!--抽取切点表达式-->
                <aop:pointcut id="myPointcut" expression="execution(* com.company.aop.*.*(..))"/>
                <aop:around method="around" pointcut-ref="myPointcut"/>
                <aop:after method="after" pointcut-ref="myPointcut"/>
            </aop:aspect>
        </aop:config>
    
    </beans>
  • 相关阅读:
    三十岁了是否该改行——我完全晕倒了
    asp.net Context.Handler 页面间传值的几种方法
    信道与信道栈
    正则表达式之字符组
    移动Web界面样式CSS3
    Media Queries语法总结
    WCF全面解析(上下册)
    HTML5移动Web开发指南
    HTML5移动开发即学即用(双色)
    可靠会话最佳实践
  • 原文地址:https://www.cnblogs.com/GumpYan/p/14188890.html
Copyright © 2011-2022 走看看