美文网首页
四、面向切面编程(AOP)(2)

四、面向切面编程(AOP)(2)

作者: 呆呆_ | 来源:发表于2017-01-21 00:15 被阅读0次

1.在applicationContext中增加aop命名空间

2. pointcut

    <!--AOP begin-->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
    <bean id="testAspect" class="com.xxxx.fabu.aspect.TestAspect"/>

    <!--要求进入到AOP的配置,重点配置切入点,以及确定切入的处理操作方法-->
    <aop:config>
        <aop:pointcut id="pointCut" expression="execution(* com.xxxx.fabu.service..*.*(..))"/>
        <aop:aspect ref="testAspect"><!--进行切面的配置,如果是切面控制应该有一个控制的类-->
            <aop:before method="beforeMethod" pointcut-ref="pointCut"/>
            <aop:after method="afterMethod" pointcut="execution(* com.xxxx.fabu.service..*.*(..))"/>
        </aop:aspect>
    </aop:config>
    <!--AOP end-->
execution(* com.sample.service.impl..*.*(..))

解释如下:

符号 含义
execution() 表达式的主体
第一个* 表示任意类型的返回值
com.sample.service.impl AOP所切的服务的包名,即,我们的业务部分
包后面的两个.. 表示当前的包及子包
第二个* 类名,*表示所有类
.*(..) 表示任何方法名,括号表示参数,两个点表示任何参数类型
Paste_Image.png Paste_Image.png

3.实现参数接收

Java代码修改:

public class TestAspect {

    public void beforeMethod(Object obj) {
        if (obj instanceof CheckItem) {
            CheckItem item = (CheckItem)obj;
            System.out.println("beforeMethod 传进来的参数"+item.getTitle()+"--"+item.getDetail());
        }
        System.out.println("beforeMethod*******"+obj);
    }

    public void afterMethod() {
        System.out.println("afterMethod*******");
    }
}

修改:applicationContext.xml

    <aop:config>
        <aop:pointcut id="pointCut" expression="execution(* com.xxxx.fabu.service..*.*(..)) and args(id)"/>
        <aop:aspect ref="testAspect"><!--进行切面的配置,如果是切面控制应该有一个控制的类-->
            <aop:before method="beforeMethod" pointcut-ref="pointCut" arg-names="id"/>
            <aop:after method="afterMethod" pointcut="execution(* com.xxxx.fabu.service..*.*(..))"/>
        </aop:aspect>
    </aop:config>

4.返回值

5.异常处理

6.环绕通知

环绕通知包含了以上所有处理,不再需要编写3个处理

7.使用Annotation配置AOP

删除之前的xml配置,添加如下:

<aop:aspectj-autoproxy/>

修改TestAspect.java文件


@Aspect
@Component
public class TestAspect {

    @Before(value = "execution(* com.xxxx.fabu.service..*.*(..)) and args(checkItem)", argNames = "checkItem")
    public void beforeMethod(Object obj) {
        if (obj instanceof CheckItem) {
            CheckItem item = (CheckItem)obj;
            System.out.println("beforeMethod 传进来的参数"+item.getTitle()+"--"+item.getDetail());
        }
        System.out.println("beforeMethod*******"+obj);
    }

    @After(value = "execution(* com.xxxx.fabu.service..*.*(..))")
    public void afterMethod() {
        System.out.println("afterMethod*******");
    }

    @AfterReturning(value = "execution(* com.xxxx.fabu.service..*.*(..))", returning = "v", argNames = "v")
    public void returnMethod(Object val) {//处理返回值
        System.out.println("returnMethod:"+val);
    }

    @AfterThrowing(value = "execution(* com.xxxx.fabu.service..*.*(..))", throwing = "e", argNames = "e")
    public void throwMethod(Exception e){//对异常处理
        System.out.println("发生了错误");
    }

    @Around(value = "execution(* com.xxxx.fabu.service..*.*(..))")
    public Object aroundMethod(ProceedingJoinPoint point) throws Exception {
        System.out.println("@@@@@@环绕通知 aroundMethod ");
        return true;
    }
}


ps:

1.发生错误如下


org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'checkServiceImpl' is expected to be of type 'com.xxxx.fabu.service.CheckServiceImpl' but was actually of type 'com.sun.proxy.$Proxy12'

    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:378)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1087)

参考:
http://ekisstherain.iteye.com/blog/1569236
添加:

<aop:aspectj-autoproxy proxy-target-class="true"/>

相关文章

网友评论

      本文标题:四、面向切面编程(AOP)(2)

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