我爱编程

Spring学习笔记(七、Spring AOP API)

2017-06-19  本文已影响971人  鲁克巴克诗

上一篇:Spring学习笔记(六、Spring AOP基本概念)

一、Spring AOP API

1. Pointcut

package test16;
/**
 * Created by amber on 2017/6/19.
 */
public interface BizLogic {
    String save();
}

创建实现类BizLogincImpl :

package test16;
/**
 * Created by amber on 2017/6/19.
 */
public class BizLogincImpl implements BizLogic {
    public String save() {
        System.out.println("BizLogincImpl:save");
        return "BizLogincImpl:save";
    }
}

applicationContext:

  <bean id="bizLogincTarget" class="test16.BizLogincImpl"></bean>
    <bean id="pointcutBean" class="org.springframework.aop.support.NameMatchMethodPointcut">
        <property name="mappedNames">
            <list>
                <value>sa*</value>
            </list>
        </property>
    </bean>

2. Before advice

package test16;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
/**
 * Created by amber on 2017/6/19.
 */
public class BeforeAdvice implements MethodBeforeAdvice {
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("我是前置通知,拦截的方法名:" + method.getName() + "  目标类名:" + target.getClass().getName());
    }
}

3. Throws advice

public void afterThrowing(Exception ex)
public void afterThrowing(RemoteException ex)
public void afterThrowing(Method method,Object[] args,Object target,Exception ex)
public void afterThrowing(Method method,Object[] args,Object target,ServletException ex)

创建MyThrowsAdvice类:

package test16;
import org.springframework.aop.ThrowsAdvice;
import java.lang.reflect.Method;
/**
 * Created by amber on 2017/6/19.
 */
public class MyThrowsAdvice implements ThrowsAdvice {
    public void afterThrowing(Exception ex) {
        System.out.println("抛出异常通知: afterThrowing 1");
    }
    public void afterThrowing(Method method, Object[] objects, Object target, Exception ex) {
        System.out.println("抛出异常通知: afterThrowing 2,出现异常的方法名:" + method.getName() + "   出现异常的类名:" + target.getClass().getName());
    }
}

4. After Returning advice

package test16;
import java.lang.reflect.Method;
/**
 * Created by amber on 2017/6/19.
 */
public class AfterReturningAdvice implements org.springframework.aop.AfterReturningAdvice {
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
         System.out.println("我是返回后通知, 拦截的方法名:"+method.getName()+"  目标类名:"+target.getClass().getName()+"  返回的值:"+returnValue );
    }
}

5. Interception around advice

package test16;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
 * Created by amber on 2017/6/19.
 */
public class MethodInterception implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("MethodInterceptor(类似环绕通知) invoke 1,拦截的方法: "+invocation.getMethod().getName()+"  拦截的目标类名:"+invocation.getStaticPart().getClass().getName());
        Object obj=invocation.proceed();
        System.out.println("MethodInterceptor(类似环绕通知) invoke 2,拦截的目标: "+obj);
        return obj;
    }
}

6. Introduction advice

7. Advisor API in Spring

二、ProxyFactoryBean

关于CGLIB动态代理,参考:CGLib动态代理原理及实现
关于JDK动态代理,参考:JDK动态代理实现原理

1. Proxying interfaces

 <bean id="beforeAdvice" class="test16.BeforeAdvice"/>
    <bean id="afterReturningAdvice" class="test16.AfterReturningAdvice"/>
    <bean id="methodInterception" class="test16.MethodInterception"/>
    <bean id="myThrowsAdvice" class="test16.MyThrowsAdvice"/>
    <bean id="bizLogincTarget" class="test16.BizLogincImpl"></bean>

    <bean id="pointcutBean" class="org.springframework.aop.support.NameMatchMethodPointcut">
        <property name="mappedNames">
            <list>
                <value>sa*</value>
            </list>
        </property>
    </bean>
    <bean id="defaultAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <property name="advice" ref="beforeAdvice"/>
        <property name="pointcut" ref="pointcutBean"/>
    </bean>
    <bean id="bizLogicImpl" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target">
            <ref bean="bizLogincTarget"/>
        </property>
        <property name="interceptorNames">
            <list>
                <value>defaultAdvisor</value>
                <value>afterReturningAdvice</value>
                <value>methodInterception</value>
                <value>myThrowsAdvice</value>
            </list>
        </property>
    </bean>
  @Test
    public void test16() {
        BizLogic logic=super.getBean("bizLogicImpl");
        logic.save();
    }
Paste_Image.png
    <bean id="beforeAdvice" class="test16.BeforeAdvice"/>
    <bean id="afterReturningAdvice" class="test16.AfterReturningAdvice"/>
    <bean id="methodInterception" class="test16.MethodInterception"/>
    <bean id="myThrowsAdvice" class="test16.MyThrowsAdvice"/>
    <bean id="bizLogicTarget" class="test16.BizLogincImpl"></bean>
    <bean id="bizLogicImpl" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces">
            <value>test16.BizLogic</value>
        </property>
        <property name="target">
            <ref bean="bizLogicTarget"/>
        </property>
        <property name="interceptorNames">
            <list>
                <value>beforeAdvice</value>
                <value>afterReturningAdvice</value>
                <value>methodInterception</value>
                <value>myThrowsAdvice</value>
            </list>
        </property>
    </bean>

结果:

Paste_Image.png
<property name="target">
            <ref bean="bizLogicTarget"/>
        </property>
引用beanId替换成直接引用路径。
  <property name="target">
            <bean class="test16.BizLogincImpl"/>
        </property>
 <bean id="beforeAdvice" class="test16.BeforeAdvice"/>
    <bean id="afterReturningAdvice" class="test16.AfterReturningAdvice"/>
    <bean id="methodInterception" class="test16.MethodInterception"/>
    <bean id="myThrowsAdvice" class="test16.MyThrowsAdvice"/>
    <bean id="bizLogicTarget" class="test16.BizLogincImpl"></bean>
    <bean id="bizLogicImpl" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces">
            <value>test16.BizLogic</value>
        </property>
        <property name="target">
            <bean class="test16.BizLogincImpl"/>
        </property>
        <property name="interceptorNames">
            <list>
                <value>beforeAdvice</value>
                <value>afterReturningAdvice</value>
                <value>methodInterception</value>
                <value>myThrowsAdvice</value>
            </list>
        </property>
    </bean>

结果:

Paste_Image.png

三、Proxing classes

1. CGLIB的代理对用户来说是透明的,需要注意:

2. 使用global advisors

<bean id="beforeAdvice" class="test16.BeforeAdvice"/>
    <bean id="afterReturningAdvice" class="test16.AfterReturningAdvice"/>
    <bean id="methodInterception" class="test16.MethodInterception"/>
    <bean id="myThrowsAdvice" class="test16.MyThrowsAdvice"/>
    <bean id="bizLogicTarget" class="test16.BizLogincImpl"></bean>

    <bean id="bizLogicImpl" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces">
            <value>test16.BizLogic</value>
        </property>
        <property name="target">
            <bean class="test16.BizLogincImpl"/>
        </property>
        <property name="interceptorNames">
            <list>
                <value>beforeAdvice</value>
                <value>afterReturningAdvice</value>
                <value>method*</value>//只适用于实现了MethodInterceptor接口的拦截器,其他advice不适用哦!!!
                <value>myThrowsAdvice</value>
            </list>
        </property>
    </bean>

3. 简化的Proxy定义

    <bean id="beforeAdvice" class="test16.BeforeAdvice"/>
    <bean id="afterReturningAdvice" class="test16.AfterReturningAdvice"/>
    <bean id="methodInterception" class="test16.MethodInterception"/>
    <bean id="myThrowsAdvice" class="test16.MyThrowsAdvice"/>
    <bean id="baseProxyBean" class="org.springframework.aop.framework.ProxyFactoryBean" lazy-init="true" abstract="true"/>
    <bean id="bizLogicImpl" parent="baseProxyBean">//将baseProxyBean作为父类
        <property name="target">
            <bean class="test16.BizLogincImpl"/>//直接引用实现类
        </property>
        <property name="proxyInterfaces">
            <value>test16.BizLogic</value>
        </property>
        <property name="interceptorNames">
            <list>
                <value>beforeAdvice</value>
                <value>afterReturningAdvice</value>
                <value>methodInterception</value>
                <value>myThrowsAdvice</value>
            </list>
        </property>
    </bean>

结果:


Paste_Image.png

4. 使用ProxyFactory

5. 使用auto-proxy

Paste_Image.png Paste_Image.png

下一篇:Spring学习笔记(八、Spring对AspectJ的支持)

上一篇下一篇

猜你喜欢

热点阅读