Spring AOP


AOP是代码解耦的一种方式,将核心业务逻辑与系统级服务(日志、事务等)分离。
Spring AOP的原理是动态代理,动态代理的实现方式有三种:jdk、cglib、aspectj,Spring AOP容器会根据目标对象采取不同的动态代理实现。

动态代理

jdk动态代理

jdk动态代理要求目标类必须实现某个接口

public class ProxyTest {
    public static void main(String[] args) {
        SomeService service = new SomeServiceImpl();

        SomeService proxy = (SomeService) Proxy.newProxyInstance(service.getClass().getClassLoader(),
                service.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("proxy... "+method.toString());
                        return method.invoke(service, args);
                    }
                }
                );

        System.out.println(proxy.doService());
    }
}

interface SomeService {
    int doService();
}

class SomeServiceImpl implements SomeService {

    @Override
    public int doService() {
        System.out.println("doSrvice");
        return 123;
    }

    @Override
    public String toString() {
        return "SomeServiceImpl{}";
    }
}
/*
proxy...public abstract int SomeService.doService()
doSrvice
123
*/

cglib动态代理

cglib的动态代理是通过生成目标对象实现类的子类来实现的,这个子类对象就是代理对象。所以使用cglib动态代理要求目标类不能是final的。

public class CglibTest {
    public static void main(String[] args) {
        ServiceImpl proxy = new ServiceImplCglibProxyFactory().newProxyInstance(new ServiceImpl());
        proxy.doService();
    }
}
class ServiceImpl{
    public void doService(){
        System.out.println("doService");
    }
}
class ServiceImplCglibProxyFactory implements MethodInterceptor {
    ServiceImpl service;

    public ServiceImpl newProxyInstance(ServiceImpl service){
        this.service=service;
        Enhancer enhancer=new Enhancer();
        //设置父类为目标类
        enhancer.setSuperclass(service.getClass());
        //回调intercept方法
        enhancer.setCallback(this);
        return (ServiceImpl)enhancer.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("proxy...");

        Object invoke = method.invoke(service, args);

        return invoke;
    }
}
/*
proxy...
doService
*/

AOP的几个概念

切面Aspect

分为通知、顾问,对主业务逻辑的增强。
一般作为单独的类,定义了在什么时间、什么方法完成什么样的功能

织入Weaving

将切面插入到目标对象的过程

通知Advice

定义织入的时间点,例如前置通知、后置通知、环绕通知等,不能选择切入点

顾问Advisor

将通知进行包装,在不同的时间点将切面织入不同的切入点

连接点

可以被切面织入的方法

切入点

实际被切面织入的方法

Spring框架使用AspectJ的注解

AspectJ通知的类型

  • 前置@Before
  • 后置@AfetrReturning:可以接收返回值,不可修改返回值
  • 环绕@Around:可以修改返回值
  • 异常@AfterThrowing
  • 最终@After

使用:

posted @ 2019-02-17 15:03  darknessplus  阅读(172)  评论(0编辑  收藏  举报