Spring AOP

理解面向切面编程

面向切面编程是软件编程思想发展到一定阶段的产物,

是对面向对象编程的有益的补充.

AOP一般适用于具有横切逻辑的场合,如访问控制,事务管理,性能检测等.

AOP的目标(作用):让我们可以“专心做事”  日志记录,事务处理,异常捕获,缓存操作。

AOP原理

将复杂的需求分解出不同方面,将散布在系统中的公共功能集中解决

采用代理机制组装起来运行,在不改变原程序的基础上对代码段进行增强处理,增加新的功能

面向切面编程的基本概念

切面(Aspect):一个模块化的横切逻辑,可能会横切多个对象

连接点(Join Point):程序执行中的某个具体的执行点.

增强处理(Advice):切面在某个特定的连接点上执行的代码逻辑

切入点(Pointcut):对连接点的特征进行描述,可以使用正则表达式.增强处理和一个切入点表达式相关联,并在这个切入点匹配的某个连接点上运行.

目标对象(Target object):被一个或者多个切面增强的对象.

AOP代理(AOP proxy):由AOP框架所创建的对象,实现执行增强处理方法等功能.

织入(Weaving):将增强处理连接到应用程序中的类型或对象上的过程.

增强处理类型:前置增强,后置增强,环绕增强,异常抛出增强,最终增强等类型

使用Spring AOP实现日志输出

新建一个类

package cn.baby.entity;

/**
 * Created by Administrator on 2017/10/18.
 */
public class HelloSpring {
    private String who=null;

    public String getWho() {
        return who;
    }

    public void setWho(String who) {
        this.who = who;
    }

    //输出方法
    public void print(){
        System.out.println("Hello,"+this.getWho()+"!");
    }
}

写增强方法

package cn.baby.aop;

import cn.baby.entity.HelloSpring;
import org.aspectj.lang.JoinPoint;
import sun.rmi.runtime.Log;

import java.util.Arrays;
import java.util.logging.Logger;

/**
 * Created by Administrator on 2017/10/18.
 */
public class UserServiceLogger {
    private static final Logger log=Logger.getLogger(String.valueOf(UserServiceLogger.class));
    //代表前置增强
    public void before(JoinPoint jp){
        log.info("我是日志"+jp.getTarget()+jp.getSignature().getName()+ Arrays.toString(jp.getArgs()));
    }
    //代表后置增强
    public void afterReturning(JoinPoint jp,Object result){
        log.info(jp.getTarget()+jp.getSignature().getName()+ result);
    }
}

配置Spring配置文件

<?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-3.2.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
">
    <!--通过bean元素声明需要Spring创建的实例.该实例属性的类型通过class属性来指定并通过id属性为实例指定一个名称,以便于访问-->
    <bean id="helloSpring" class="cn.baby.entity.HelloSpring">
        <!--通过property元素用来为实例的属性赋值-->
        <property name="who">
            <value>Spring</value>
        </property>
    </bean>
    <bean id="theLogger" class="cn.baby.aop.UserServiceLogger"></bean>
    <aop:config>
        <!--定义一个切入点表达式-->
        <aop:pointcut id="pointcut" expression="execution(public void print())"/>
        <!--将before()方法定义为前置增强并引用poincut切入点-->
        <aop:aspect ref="theLogger">
            <aop:before method="before" pointcut-ref="pointcut"></aop:before>
            <!--将afterReturning()方法定义为后置增强并引用poincut切入点result作为参数-->
            <aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>
        </aop:aspect>
    </aop:config>
</beans>

写测试类

  @Test
    public void show()
    {
        //实例化Spring
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext-hello.xml");
        //通过ApplicationContext的getBen方法,根据id来获取Bean的实例
        HelloSpring hellospring = (HelloSpring) context.getBean("helloSpring");
        hellospring.print();
    }

结果图

原文地址:https://www.cnblogs.com/liuzhiw/p/7688988.html