例子
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是否在拦截范围之内,如果在,则生成代理对象,把匹配的拦截器也加入到代理对象中。
来源:https://www.cnblogs.com/benx/p/3420003.html