Spring AOP 方式四 Aspect 基于Schema

例子

Spring 配置文件

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd 
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

    <context:component-scan base-package="com.benx.mvc" />


    <bean class="com.benx.aspectj.service.HelloImpl" />


    <bean id="monitor" class="com.benx.aspectj.HelloMonitor" />


    <aop:config>
        <aop:aspect id="helloMonitor" ref="monitor">
            <aop:pointcut id="businessService"
                expression="execution(* com.benx.aspectj.service.*.*(..))" />

            <aop:before pointcut-ref="businessService" method="before" />
            <aop:after pointcut-ref="businessService" method="after" />
            <aop:after-returning pointcut-ref="businessService" method="afterReturning" returning="result" />
            <aop:after-throwing pointcut-ref="businessService" method="afterThrowing" throwing="ex" />
            <aop:around pointcut-ref="businessService" method="around"/>
        </aop:aspect>
    </aop:config>

</beans>

 

接口类

package com.benx.aspectj.service;

public interface IHello {

    public String say();

}

 

接口实现类

package com.benx.aspectj.service;

public class HelloImpl implements IHello {

    public String say() {
        String msg = "Hello World";
        System.out.println(msg);
        return msg;
    }

}

 

监听器

package com.benx.aspectj;

import org.aspectj.lang.ProceedingJoinPoint;

public class HelloMonitor {

    public void before() {
        System.out.println("start");
    }

    public void after() {
        System.out.println("end");
    }

    public void afterReturning(Object result) {
        System.out.println("afterReturning ");
        System.out.println(result);
    }

    public void afterThrowing(Exception ex) {
        System.out.println("afterThrowing" + ex.getMessage());
    }

    public Object around(ProceedingJoinPoint call) {
        System.out.println("around start");

        Object ob = null;
        try {
            ob = call.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            System.out.println("around end");
            
        }
        return ob;

    }

}

 

测试类

package com.benx.aspectj;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.benx.aspectj.service.IHello;

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {

        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("com/benx/aspectj/aspectj_spring.xml");

        IHello hello = context.getBean(IHello.class);

        hello.say();
        
    }

}

执行结果:

start
around start
Hello World
around end
afterReturning
Hello World
end

 

 

实现原理:

xml的命名空间aop的解析类ConfigBeanDefinitionParser负责解析,步骤:

1、先注入AspectJAwareAdvisorAutoProxyCreator到spring context中,该类生成代理类

2、解析aop:pointcut   代表匹配路径

3、解析 aop:before  aop:after 代表拦截器,每个拦截器包含了pointcut(过滤器表达式)和Method

 

 

生成代理流程,执行AspectJAwareAdvisorAutoProxyCreator的postProcessAfterInitialization方法,该方法在bean执行init方法后执行,然后遍历所有拦截器,根据拦截器的pointcut表达式来判断该Bean是否在拦截范围之内,如果在,则生成代理对象,把匹配的拦截器也加入到代理对象中。

 

posted @ 2013-11-12 18:04  benx621  阅读(411)  评论(0编辑  收藏  举报