Spring - xml方式配置通知的参数 & 返回值(14)

由于环绕通知有前置通知和后置通知结合特优点,所以这里只说环绕通知。实际上是我测试了好久前置通知,总是有错,就放弃了,以后遇到了再说…

切点带参数

如果切点中存在参数,若需要只拦截这个方法,execution中的参数需要配置全类名,如:

public Integer delete(String userId, Double type) {
    System.out.println(userId);
    System.out.println(type);
    return 100;
}
<aop:pointcut expression="execution(Integer com.spring.aopxml.UserDaoImpl.delete
            (java.lang.String, java.lang.Double))" id="cut1"/>

环绕通知中获得切点的参数

public class UserDaoImpl implements UserDao {
    public Integer delete(String userId, Double type) {
        System.out.println("delete : " + userId);
        System.out.println("delete : " + type);
        return 100;
    }

    public Boolean delete(Double type, String userId) {
        System.out.println("delete : " + userId + " " + type);
        return true;
    }
}
import org.aspectj.lang.ProceedingJoinPoint;

public class MyAspectJ {
    public Integer around(ProceedingJoinPoint pjp) throws Throwable {
        //获得参数
        Object[] args = pjp.getArgs();
        for(Object o : args)
            System.out.println("args   " + o);
        if((Double)args[1] < 100.0)
            return null;
        //执行切点
        Integer proceed = (Integer)pjp.proceed();
        return proceed;
    }
}
<bean id="userDao" class="com.spring.aopxml.UserDaoImpl"></bean>
<bean id="myAspectJ" class="com.spring.aopxml.MyAspectJ"></bean>
<aop:config>
    <aop:pointcut expression="execution(Integer com.spring.aopxml.UserDaoImpl.delete(java.lang.String, java.lang.Double))" id="cut1"/>
    <aop:aspect ref="myAspectJ">
        <aop:around method="around" pointcut-ref="cut1" />
    </aop:aspect>
</aop:config>
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao ud = (UserDao)ac.getBean("userDao");
        Integer delete = ud.delete("11", 100.0);
        System.out.println(delete);
        /*Console
         *      args   11
                args   100.0
                delete : 11
                delete : 100.0
                100              * */
    }
}

环绕通知中获得切点的类型

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;

public class MyAspectJ {
    public Integer around(ProceedingJoinPoint pjp) throws Throwable {
        //获得切点方法的方法签名
        //有接口是接口上的方法签名,没有接口时是类上的方法签名
        Signature signature = pjp.getSignature();
        System.out.println(signature);

        //获得切点所在的实例
        Object target = pjp.getTarget();
        System.out.println(target);
        //执行切点
        Integer proceed = (Integer)pjp.proceed();
        return proceed;
    }
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        /*
         * 如果userDao对应的类有接口,这里不能使用UserDaoImpl,因为Spring的AOP底层在实现动态代理时,
         * 如果bean存在接口,则使用JDK动态代理,这样创建的实例是和原接口实例同级别的。
         * 如果bean不存在接口,会使用Cglib动态代理,这样创建的类是bean的子类,可以是使用bean接受
         * */
        UserDao ud = (UserDao)ac.getBean("userDao");
        Integer delete = ud.delete("11", 100.0);
        System.out.println(delete);
        /*Console
         *      Integer com.spring.aopxml.UserDao.delete(String,Double)
                com.spring.aopxml.UserDaoImpl@56a6d5a6
                delete : 11
                delete : 100.0
                100                          * */
    }
}

猜你喜欢

转载自blog.csdn.net/qq_38206090/article/details/82686047
今日推荐