spring AOP--AspectJ---xml
原创
©著作权归作者所有:来自51CTO博客作者qq5963a5404b339的原创作品,请联系作者获取转载授权,否则将追究法律责任
基于xml的AspectJ
1.AspectJ介绍
AspectJ是一个基于Java语言的AOP框架,他提供了强大的AOP功能。Spring2.0以后,SpringAOP引入了对AspectJ的支持。
使用AspectJ实现AOP有两种方式:
1.基于xml的声明式AspectJ;
2.基于注解的声明式AspectJ;
2.aop:config
spring配置文件中的元素下可以包含多个aop:config元素,一个aop:config元素中又可以包含属性和子元素。
其层级关系如上图所示。
3.如何配置
3.1配置切面
aop:aspect元素
id用于定义该切面的唯一标识;
ref用于引用普通的SpringBean;
3.2配置切入点
aop:pointcut元素
当aop:pointcut是aop:config的直接子元素时,表示全局的切入点。
如果aop:pointcut是aop:aspect的直接子元素时,表示局部切入点。
id用于指定切入点的唯一标识;
expression用于指定切入点关联的切入点表达式。
切入点表达式:
execution(* com.bean.*.*(..))
其中execution()是表达式的主体
第一个*表示方法的返回类型
第一个表示XXX类
第二个表示的是XXX方法
两个点表示的是任意参数
springAOP中切入点表达式的基本格式如下:
execution(modifiers-pattern?ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern)
modifiers-pattern:表示定义的目标方法的访问修饰符:public,private…
ret-type-pattern:表示定义的目标方法的返回值类型:void,String…
declaring-type-pattern:表示定义的目标方法的类路径:com.bean。。。。
name-pattern:表示具体需要被代理的目标方法:add()。。。
param-pattern:表示需要被代理的目标方法包含的参数;
throws-pattern:表示需要被代理的目标方法抛出的异常类型。
其他带有?的标识都是选填项。
3.3配置通知
pointcut:该属性用于指定一个切入点表达式
pointcut-ref该属性指定一个已经存在的植入点名称
pointcut与pointcut-ref二选一
method该属性指定一个方法名,指定将切面bean中的该方法转换为增强处理
throwing该属性支队after-throwing元素有效,用于指定一个形参名,异常通知方法可以通过改形参访问目标方法所抛出的异常
returning该属性支队after-returning元素有效,用于指定衣蛾形参名,后置通知方法可以通过该形参访问目标增强方法的返回值。
4.例子
4.1准备
aspectjrt-1.8.10.jar
aspectjweaver-1.8.10.jar
4.2创建一个spring工程
4.3创建Java文件
package aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
//@Aspect
//@Component("aspect")
public class MyAspect {
public void before(){
System.out.println("前置通知");
System.out.println("MyAspect#before");
}
public void after(JoinPoint joinpoint){
System.out.println("后置通知");
System.out.println("MyAspect#after");
System.out.println(joinpoint.getSignature().getName());
}
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("MyAspect#around#before");
System.out.println("环绕通知#前置通知");
Object object = proceedingJoinPoint.proceed();
System.out.println("环绕通知#后置通知");
System.out.println("MyAspect#around#after");
return object;
}
public void afterThrow(JoinPoint joinPoint,Throwable e){
System.out.println("异常通知");
System.out.println("MyAspect#afterThrow");
System.out.println(e.getMessage());
}
public void afterAfter(){
System.out.println("最终通知");
System.out.println("MyAspect#after#after");
}
}
package bean;
import org.springframework.stereotype.Component;
//@Component("people")
public class People{
/**
*
*/
private static final long serialVersionUID = 6664089908413976436L;
public void say(){
System.out.println("People#say");
// int a = 3/0;
}
}
package client;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import bean.People;
public class Main {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"resource/*.xml");
People people = (People) applicationContext.getBean("people");
people.say();
}
}
4.4xml文件
bean.xml
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 目标bean -->
<context:annotation-config/>
<!-- 指定需要扫描的包 -->
<!--
<context:component-scan base-package="bean,aspect"></context:component-scan>
-->
<bean id="people" class="bean.People"></bean>
<!-- 增强类 -->
<bean id="aspect" class="aspect.MyAspect"></bean>
<!-- aop编程 -->
<aop:config>
<!-- 配置切面 -->
<aop:aspect ref="aspect">
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* bean.*.*(..))" id="aspectPoint"/>
<!-- 关联切入点和增强类 -->
<!-- 前置通知 -->
<aop:before method="before" pointcut-ref="aspectPoint"/>
<!-- 后置通知 -->
<aop:after-returning method="after" pointcut-ref="aspectPoint" returning="returnVal"/>
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="aspectPoint"/>
<!-- 异常通知 -->
<aop:after-throwing method="afterThrow" pointcut-ref="aspectPoint" throwing="e"/>
<!-- 最终通知 -->
<aop:after method="afterAfter" pointcut-ref="aspectPoint"/>
</aop:aspect>
</aop:config>
</beans>
4.5运行结果
前置通知
MyAspect#before
MyAspect#around#before
环绕通知#前置通知
People#say
最终通知
MyAspect#after#after
环绕通知#后置通知
MyAspect#around#after
后置通知
MyAspect#after
say
5.总结
AspectJ 是一个基于Java的AOP框架,spring2.0之后
SpringAOP引入对AspectJ的支持,并允许直接进行编程。