• Spring(五)AOP简述


    原文出自:http://www.cnblogs.com/liunanjava/p/4401241.html

    一、AOP简述

    AOP全称是:aspect-oriented programming,它是面向切面编号的思想核心,

    AOP和OOP既面向对象的编程语言,不相冲突,它们是两个相辅相成的设计模式型

    AOP技术弥补了面向对象编程思想的不足,spring aop是实现aop的一种技术,srping aop是spring框架中某个子框架或者子功能所依赖的核心。

    SPring的容器并不依赖于AOP

    这意味着程序员可以自己选择是否使用aop技术,aop提供强大的中间件解决方案,这使spring ioc容器更加的完善。

    二、一些术语

    2.1、术语

    • Cross-cutting concern:系统层面上的服务穿插到业务逻辑的处理流程之中
    • Aspect:当需要时,将其放到应用程序之上,不需要时,将其从应用程序中脱离出来
    • Advcie:是Aspect具体的实现,advice包括cross-cutting conerns的行为或者所提供的服务
    • Joinpoint:Aspect在应用程序执行时加入业务流程的时机
    • Pointcut:指定某个aspect在哪些joinpoint时被穿插至应用程序之上
    • Target:一个advice被应用的对象或者目标对象
    • Instruction:为已经编写,编译完成的类,在执行时期动态的加入一些方法而不用修改或者增加任何代码
    • Weave:被应用到对象之上的过程

    2.2、Spring对AOP的支持

    纯Java语言来编写

    定义pointcutes可以使用配置文件

    不支持属性成员的jointpoints.(spring 设计思想认为支持属性成员的jointpoints会破坏对象的封装性)

    三、Spring创建Advice

    3.1、Before Advice

    目标对象的方法执行之前被调用

    通过实现MethodBeforeAdvice接口来实现

    MethodBeforeAdvice 继承自BeforeAdvice,而BeforeAdvice又继承Advice接口,before方法会在目标对象target所指定的方法执行之前被调用执行。before返回值为void,没有返回值,在before方法执行完成之后,才开始执行目标对象的方法.

     3.2、实例

    package com.pb;
    /**
     * 接口
     * @author Administrator
     *
     */
    public interface IHello {
    
        public void sayHello(String str);
        
    }
    package com.pb;
    /**
     * 接口实现类
     * @author Administrator
     *
     */
    public class Hello implements IHello {
    
        @Override
        public void sayHello(String str) {
            System.out.println("Hello    "+str);
    
        }
    
    }

    代理类

    package com.pb;
    
    import java.lang.reflect.Method;
    
    import org.springframework.aop.MethodBeforeAdvice;
    /**
     * 在方法执行前调用
     * @author Administrator
     *实现了MethodBeforeAdvcie接口
     */
    public class SayHelloBeforeAdvice implements MethodBeforeAdvice {
    
        @Override
        public void before(Method arg0, Object[] arg1, Object arg2)
                throws Throwable {
            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:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
    
    <!-- 建立目标对象实例 -->
    <bean id="hello" class="com.pb.Hello"/>
    <!--  设定Advice实例-->
    <bean id="sayBeforeAdvice" class="com.pb.SayHelloBeforeAdvice" />
    <!-- 建立代理对象 -->
    <bean id="hellProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <!-- 设置代理接口 -->
    <property name="proxyInterfaces">
    <value>com.pb.IHello</value>
    </property>
    <!--  设置目标对象实例-->
    <property name="target">
    <ref local="hello"/>
    </property>
    <!--  设定Advice实例-->
    <property name="interceptorNames">
    <list>
    <value>sayBeforeAdvice</value>
    </list>
    </property>
    </bean>
    
    </beans>

    测试类

    package com.pb;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * 测试类
     * @author Administrator
     *
     */
    public class Test {
    
        public static void main(String[] args) {
            ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
            IHello iHello=(IHello) context.getBean("hellProxy");
            iHello.sayHello("AOP"); 
        }
    
    }

    结果:

    ====在方法执行前调用======
    Hello    AOP

    3.3、After Advice

    在目标对象方法执行之后被调用

    通过实现AfterReturningAdvice接口来实现

    在以上代码上增加

    package com.pb;
    
    import java.lang.reflect.Method;
    
    import org.springframework.aop.AfterReturningAdvice;
    /*
     * 在方法执行完后调用 
     * 实现 AfterRetruningAdvice接口
     */
    public class SayAfterAdvice implements AfterReturningAdvice {
    
        @Override
        public void afterReturning(Object arg0, Method arg1, Object[] arg2,
                Object arg3) throws Throwable {
            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:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
    
    <!-- 建立目标对象实例 -->
    <bean id="hello" class="com.pb.Hello"/>
    <!--  设定beforAdvice实例-->
    <bean id="sayBeforeAdvice" class="com.pb.SayHelloBeforeAdvice" />
    <!-- 设定AfterAdvice实例 -->
    <bean id="sayAfterAdvice" class="com.pb.SayAfterAdvice" />
    <!-- 建立代理对象 -->
    <bean id="hellProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <!-- 设置代理接口 -->
    <property name="proxyInterfaces">
    <value>com.pb.IHello</value>
    </property>
    <!--  设置目标对象实例-->
    <property name="target">
    <ref local="hello"/>
    </property>
    <!--  设定Advice实例-->
    <property name="interceptorNames">
    <list>
    <value>sayBeforeAdvice</value>
    <value>sayAfterAdvice</value>
    </list>
    </property>
    </bean>
    </beans>

    测试类不变,结果:

    ====在方法执行前调用======
    Hello    AOP
    =========在方法执行完后调用=======

    3.4、Around Advice

    在方法执行之间和之后来执行相应的操作

    要实现接口MethodInterceptor接口

    package com.pb;
    
    import org.aopalliance.intercept.MethodInterceptor;
    import org.aopalliance.intercept.MethodInvocation;
    
    
    public class SayAroundAdvice implements MethodInterceptor {
    
        @Override
        public Object invoke(MethodInvocation arg0) throws Throwable {
            System.out.println("=========在方法执行之前做点事情");
            Object result=arg0.proceed();
            System.out.println("在方法执行之后做点事情=========");
            return result;
        }
    
        
    
    }

    配置文件

    <?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:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
    
    <!-- 建立目标对象实例 -->
    <bean id="hello" class="com.pb.Hello"/>
    <!--  设定beforAdvice实例-->
    <bean id="sayBeforeAdvice" class="com.pb.SayHelloBeforeAdvice" />
    <!-- 设定AfterAdvice实例 -->
    <bean id="sayAfterAdvice" class="com.pb.SayAfterAdvice" />
    <!-- 设定AroundAdvice实例 -->
    <bean id="sayRoundAdvice" class="com.pb.SayAroundAdvice" />
    <!-- 建立代理对象 -->
    <bean id="hellProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <!-- 设置代理接口 -->
    <property name="proxyInterfaces">
    <value>com.pb.IHello</value>
    </property>
    <!--  设置目标对象实例-->
    <property name="target">
    <ref local="hello"/>
    </property>
    <!--  设定Advice实例-->
    <property name="interceptorNames">
    <list>
    <!-- <value>sayBeforeAdvice</value>
    <value>sayAfterAdvice</value> -->
    <value>sayRoundAdvice</value>
    </list>
    </property>
    </bean>
    
    </beans>

    3.5、THrowsAdvice

    异常发生的时候,通知某个服务对象做处理

    实现ThrowsAdvice接口

    package com.pb;
    
    import java.lang.reflect.Method;
    
    import org.springframework.aop.ThrowsAdvice;
    
    public class SayThowsAdvice implements ThrowsAdvice {
        
        public void afterThrowing(Method method,Object[] objs,Object target,Throwable ta){
            System.out.println("异常发生: "+ta+" 抛出异常的是: "+method);
        }
    }

    四、基于XML Schema

    简化代码实现

    容易对应程序进行维护

    所有元素都定义在<aop:config>中

     

    五、基于Annotation

    以注解的方式对Java普通类进行标注

  • 相关阅读:
    0705-深度网络模型持久化
    0704-使用GPU加速_cuda
    0703-可视化工具tensorboard和visdom
    0702-计算机视觉工具包torchvision
    00-凸优化引言
    MySQL数据库从入门到放弃(目录)
    0701-数据处理
    BurpSuite抓取HTTPS请求&&拦截Android请求
    数学里的e到底指什么
    QGeoPolygon
  • 原文地址:https://www.cnblogs.com/vincent-blog/p/4415013.html
Copyright © 2020-2023  润新知