4. AOP

2019-10-12  本文已影响0人  月影追猎者

AOP (Aspect Oriented Programming),面向切面编程,通过预编译方式与运行期动态代理实现程序功能的统一维护的技术。利用AOP可以对业务逻辑进行隔离,使业务逻辑间耦合度降低,提高可重用性,提高开发效率。

动态代理

/**
 * 接口
 */
public interface Subject {
    void request();
}
/**
 * 实体类
 */
public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("核心方法");
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 动态代理类
 * 生成对象的代理对象
 */
public class DynamicProxy implements InvocationHandler {

    private Object obj; // 被代理对象

    public DynamicProxy(Object obj) {
        this.obj = obj;
    }

    /**
     * 生成obj的代理对象
     */
    public Object getInstance() {
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
    }

    /**
     * 执行obj任一方法时的通知设置
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object ret = null;
        System.out.println("动态代理 - 前置通知");
        try {
            ret = method.invoke(obj, args); // 核心方法
            System.out.println("动态代理 - 后置通知");
        } catch (Exception e) {
            System.out.println("动态代理 - 例外通知");
        } finally {
            System.out.println("动态代理 - 最终通知");
        }
        return ret;
    }
}
public static void main(String[] args) {
    Subject real = new RealSubject();
    DynamicProxy proxy = new DynamicProxy(real);
    Subject sub = (Subject) proxy.getInstance();
    sub.request();
}

AOP
基于动态代理模式,将方法切出切面以进行统一控制。

  1. 编写相应的通知方法
  2. 在Spring中配置通知
public class AOP {
    /**
     * 切入点方法
     * 无参,返回值类型void,方法体无代码
     */
    public void pointcut() {

    }

    /**
     * 前置通知
     */
    public void before() {
        System.out.println("AOP类前置通知方法");
    }

    /**
     * 后置通知
     */
    public void returning() {
        System.out.println("AOP类后置通知方法");
    }

    /**
     * 例外通知
     */
    public void throwing() {
        System.out.println("AOP类例外通知方法");
    }

    /**
     * 最终通知
     */
    public void after() {
        System.out.println("AOP类最终通知方法");
    }
}

引入依赖jar包

<dependency>
    <groupId>aopalliance</groupId>
    <artifactId>aopalliance</artifactId>
    <version>1.0</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>

配置applicationContext.xml文件

<bean id="aop类id" class="AOP类全名"/>
<aop:config>
    <aop:aspect id="切面id" ref="aop类id">
        <!--
            配置切入点
            第一个*,返回值类型,*表示任意返回值类型
            第二个*,类名,*表示任意类名
            第三个*,方法名,*表示任意方法名
            (..),形参类型,..表示任意形参类型
        -->
        <aop:pointcut id="切入点id" expression="execution(* 包名.*.*(..))"/>
        <aop:before method="前置通知方法before" pointcut-ref="切入点id"/>
        <aop:after-returning method="后置通知方法returning" pointcut-ref="切入点id"/>
        <aop:after-throwing method="例外通知方法throwing" pointcut-ref="切入点id"/>
        <aop:after method="最终通知方法after" pointcut-ref="切入点id"/>
    </aop:aspect>
</aop:config>
上一篇下一篇

猜你喜欢

热点阅读