美文网首页
Spring-7-AOP

Spring-7-AOP

作者: 宠辱不惊的咸鱼 | 来源:发表于2019-10-04 09:36 被阅读0次

    概述

    分类

    • Spring-仅方法
      • JDK:动态代理-ProxyGenerator
      • CGLib:字节码生成器-ClassGenerator
    • JBoss:自定义类加载器(可属性,方法,构造器)
    • 代码生成工具:利用工具在现有代码上添加新的代码
    • 语言扩展:对方法和属性进行增强,AspectJ就是用的这种(可属性,方法,构造器)

    概念

    • 切面(Aspect):横切关注点的抽象(何时在何处做什么)(Advisor)
    • 连接点(Joinpoint):能被拦截的点,即能应用通知的点
    • 切入点(Pointcut):对连接点进行拦截的规则定义(何处)
    • 通知(Advice):拦截到连接点后要执行的代码(何时做什么)
    • 目标对象(Target):被代理者
    • 织入(Weave):将切面应用到目标对象,导致代理对象的创建(对方法的增强)
    • 引入(Introduction):运行期为类动态地添加方法或字段(对类的增强)

    常用接口

    • MethodInterceptor,MethodBeforeAdvice,AfterReturningAdvice,ThrowsAdvice

    方式

    • AspectJProxyFactory
      • Spring与AspectJ的结合
    • ProxyFactory
      • 需编程式
    • ProxyFactoryBean
      • 可声明式,借助IoC容器

    ProxyFactory

    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.setTarget(new GreetingImpl());
    proxyFactory.addAdvice(new GreetingBeforeAndAfterAdvice());
    proxyFactory.addAdvice(new GreetingAroundAdvice());
    Greeting greeting = (Greeting) proxyFactory.getProxy();
    greeting.sayHello("Jack");
    
    GreetingBeforeAndAfterAdvice implements MethodBeforeAdvice, AfterReturningAdvice
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("GreetingBeforeAndAfterAdvice: After");
    }
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("GreetingBeforeAndAfterAdvice: Before");
    }
    
    GreetingAroundAdvice implements MethodInterceptor
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        before();
        Object result = invocation.proceed();
        after();
        return result;
    }
    

    ProxyFactoryBean

    aop-001.JPG
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    
        <bean id="aAdvice" class="com.fjh.aop.AAdvice"></bean>
        <bean id="target" class="com.fjh.aop.Target"></bean>
    
        <bean id="ppp" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="proxyInterfaces">
                <value>com.fjh.aop.ITarget</value>
            </property>
            <property name="interceptorNames">
                <list>
                    <value>aAdvice</value>
                </list>
            </property>
            <property name="target">
                <ref bean="target"/>
            </property>
        </bean>
    </beans>
    
    1. 生成ppp
      1. 这里有个注意点,xml中配的接口是字符串,因为在ProxyFactoryBean中是Class<?> []类型,在IoC的populateBean过程中,有个convertForProperty的环节,把String加载生成Class对象,并作为数组元素
      2. initializeAdvisorChain
        1. 将aAdvice先裹成Advisor,塞到LinkedList<Advisor>
        2. 有适配器的影子:MethodBeforeAdviceAdapter
      3. 由DefaultAopProxyFactory获取AopProxy,可能是jdk,也可能是cglib;调用AopProxy.getProxy
        1. 配置了<aop:config proxy-target-class="true">或者没有接口,并且target本身不是接口,也不是被Proxy生成的代理类,那么采用cglib,否则采用jdk

    疑问

    xml中不配ITarget2,而Target实现2个接口,报错点在哪?

    • 因为生成的$Proxy2只实现了ITarget,所以报ClassCastException

    xml中配了ITarget2,而Target未实现ITarget2,报错点在哪?

    • 抛AopInvocationException,method.invoke(target, args),因为method不属于target的方法;不过target有个同名方法啊,怎么判断呢,判断method所属接口或类?

    相关文章

      网友评论

          本文标题:Spring-7-AOP

          本文链接:https://www.haomeiwen.com/subject/lswjpctx.html