Spring源码-AOP

1.AOP基础概念

1.1两种代理模式

CGLIB和JDK动态代理。(这里不详细讲)

1.2.SpringAOP的基础概念

ProxyFactory :Spring中进行了封装,封装出来的类叫做ProxyFactory,封装了CGLIB和JDK动态代理

Spring利用ProxyFactory来生成代理对象

示例代码:

UserService target = new UserService();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvice(new MethodInterceptor() {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("before...");
        Object result = invocation.proceed();
        System.out.println("after...");
        return result;
    }
});
UserInterface userService = (UserInterface) proxyFactory.getProxy();
userService.test();

SpringAOP涉及到的设计模式:责任链模式

代理对象在执行某个方法的时候,如果存在执行链,那么会一个一个的执行

注意:AspectJ是在编译时对字节码进行了修改(增强),而SpringAOP是在运行的时候,调用相关的代理逻辑、

1.3 Advice的分类

共5种,如下:

  1. Before Advice:方法之前执行
  2. After returning advice:方法return后执行
  3. After throwing advice:方法抛异常后执行
  4. After (finally) advice:方法执行完finally之后执行,这是最后的,比return更后
  5. Around advice:这是功能最强大的Advice,可以自定义执行顺序

注意:ThrowsAdvice 中没有固定的方法供我们重写,开放了异常的类型给我们去写。

1.4 Pointcut

切点:方法匹配Advice的时候会用到它,它是一个验证逻辑(验证哪些方法需要被AOP)

如果Pointcut匹配了,之后才会执行advice

包含ClassFilter和MethodMatcher

示例代码:

UserService target = new UserService();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvisor(new PointcutAdvisor() {
    @Override
    public Pointcut getPointcut() {
        return new StaticMethodMatcherPointcut() {
            @Override
            public boolean matches(Method method, Class<?> targetClass) {
                return method.getName().equals("testAbc");// 切点匹配
            }
        };
    }
    @Override
    public Advice getAdvice() {
        return new MethodInterceptor() {
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("before...");
                Object result = invocation.proceed();
                System.out.println("after...");
                return result;
            }
        };
    }
    @Override
    public boolean isPerInstance() {
        return false;
    }
});
UserInterface userService = (UserInterface) proxyFactory.getProxy();
userService.test();

ProxyFactoryBean

通过这种方法来定义一个UserService的Bean,并且是经过了AOP的。但是这种方式只能针对某一个

Bean。它是一个FactoryBean,所以利用的就是FactoryBean技术,间接的将UserService的代理对象作为了Bean。

@Bean
public ProxyFactoryBean userServiceProxy(){
    UserService userService = new UserService();
    ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
    proxyFactoryBean.setTarget(userService);
    proxyFactoryBean.addAdvice(new MethodInterceptor() {
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            System.out.println("before...");
            Object result = invocation.proceed();
            System.out.println("after...");
            return result;
        }
    });
    return proxyFactoryBean;
}

1.5使用@Aspect注解

加了Aspect注解,并且这个类是bean,那么他就是一个切面bean,之后在初始化后就会解析这个bean中的Pointcut和Advice

AnnotationAwareAspectJAutoProxyCreator: 使用这个类配合@Aspect就可以实现AOP

1.6 Advisor(核心)

Advisor = Advice(代理逻辑) + Pointcut(切点规则)

1.7 概念总结

Aspect:表示切面,比如被@Aspect注解的类就是切面,可以在切面中去定义Pointcut、Advice等等

Join point:就是被代理的方法

Advice代理逻辑

Pointcut:表示切点(规则),用来匹配一个或多个连接点

Target object:目标对象,被代理对象
AOP proxy:表示代理工厂

Introduction:可以为某个类介绍接口

Weaving:表示织入,表示创建代理对象的动作,这个动作可以发生在编译时期(比如 Aspejctj),或者运行时,比如Spring AOP

补充:weawing

在Java 语言中,从织入切面的方式上来看,存在三种织入方式:编译期织入、类加载期织入和运行期织入。编译期织入是指在Java编译期,采用特殊的编译器,将切面织入到Java类中;而类加载期织入则指通过特殊的类加载器,在类字节码加载到JVM时,织入切面;运行期织入则是采用CGLib工具或JDK动态代理进行切面的织入。
AspectJ采用编译期织入和类加载期织入的方式织入切面,是语言级的AOP实现,提供了完备的AOP支持。它用AspectJ语言定义切面,在编译期或类加载期将切面织入到Java类中。

AspectJ提供了两种切面织入方式,第一种通过特殊编译器,在编译期,将AspectJ语言编写的切面类织入到Java类中,可以通过一个Ant或Maven任务来完成这个操作;第二种方式是类加载期织入,也简称为LTW(Load Time Weaving)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值