实例简述Spring AOP之对AspectJ语法的支持
2016-07-13 09:26
666 查看
Spring的AOP可以通过对@AspectJ注解的支持和在XML中配置来实现,本文通过实例简述如何在Spring中使用AspectJ.
一:使用AspectJ注解:
1,启用对AspectJ的支持:
通过在Spring的配置中引入下列元素来启用Spring对AspectJ的支持:
<aop:aspectj-autoproxy />
或者(如果不是使用XSD的话)
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
2,声明一个带有@Aspect注解的类,在这个类中声明那些方法需要被'关注'(利用@Pointcut),在那些时机点进行关注(利用@Before,@AfterReturning等等...),执行'切入'的方法
3,在Spring的配置文件中定义这个'切面'类:任意带有一个@Aspect切面(拥有@Aspect注解)的bean都将被Spring自动识别并用于配置在Spring AOP.
4,使用被Spring管理的bean,在执行被'关注'的方法时,'切入'的方法就会被执行.
一个完整的例子:
需要被'切入'的类:
[java] view
plain copy
public class Monkey {
public void stealPeaches(String name) {
System.out.println(" Monkey " + name + " is stealling peaches...");
}
public void stealCorns(String name) {
System.out.println(" Monkey " + name + " is stealling corns...");
}
}
'切面'类:
[java] view
plain copy
@Aspect
public class Guardian {
@Pointcut("execution(* com.test.spring.aspectj.Monkey.stealPeaches(..))")
public void guardOrchard() {
}
@Before(value = "guardOrchard()")
public void guardOrchardBefore() {
System.out.println("Guardian spotted a monkey is approaching the orchard...");
}
@AfterReturning("guardOrchard() && args(name,..)")
public void guardOrchardAfter(String name) {
System.out.println("Guardian caught a monkey stealling peaches whoes name is " + name + "...");
}
@Around("guardOrchard() && args(name,..)")
public void guardOrchardAround(ProceedingJoinPoint joinpoint,String name) {
System.out.println("Guardian guardOrchardAround started ... " + name);
try {
joinpoint.proceed();
} catch (Throwable e) {
System.out.println("Guardian guardOrchardAround exception happened ... " + name);
}
System.out.println("Guardian guardOrchardAround completed ... " + name);
}
@Pointcut("execution(* com.test.spring.aspectj.Monkey.stealCorns(..))")
public void guardFarm() {
}
@Before(value = "guardFarm()")
public void guardFarmBefore() {
System.out.println("Guardian spotted a monkey is approaching the farm...");
}
@AfterReturning("guardFarm() && args(name,..)")
public void guardFarmAfter(String name) {
System.out.println("Guardian caught a monkey stealling corns whoes name is " + name + "...");
}
}
配置文件:
[html] view
plain copy
<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!--
<aop:aspectj-autoproxy /> equals to <bean
class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"
/>
-->
<aop:aspectj-autoproxy />
<bean id="guardian" class="com.test.spring.aspectj.Guardian" />
<bean id="monkey" class="com.test.spring.aspectj.Monkey" />
</beans>
使用bean:
[java] view
plain copy
ApplicationContext context = new ClassPathXmlApplicationContext("conf/aspectJAppcontext.xml");
Monkey monkey = (Monkey) context.getBean("monkey");
try {
monkey.stealPeaches("mighty monkey");
monkey.stealCorns("mighty monkey");
} catch (Exception e) {
}
运行结果:
[plain] view
plain copy
Guardian spotted a monkey is approaching the orchard...
Guardian guardOrchardAround started ... mighty monkey
Monkey mighty monkey is stealling peaches...
Guardian caught a monkey stealling peaches whoes name is mighty monkey...
Guardian guardOrchardAround completed ... mighty monkey
Guardian spotted a monkey is approaching the farm...
Monkey mighty monkey is stealling corns...
Guardian caught a monkey stealling corns whoes name is mighty monkey...
二:通过XML配置AspectJ实现AOP:在java类中定义要被'方面'调用的切入方法,在XML中配置.
例子:被'切入'的类,普通java类:
[java] view
plain copy
public class Monkey {
public void stealPeaches(String name) {
System.out.println(" Monkey " + name + " is stealling peaches...");
}
public void stealCorns(String name,int numberToSteal) {
System.out.println(" Monkey " + name + " is stealling corns...");
}
}
定义要被'方面'调用的切入方法的类:
[java] view
plain copy
public class XMLGuardian {
public void guardOrchardBefore() {
System.out.println("XMLGuardian spotted a monkey is approaching the orchard...");
}
public void guardOrchardAfter() {
System.out.println("XMLGuardian caught a monkey stealling peaches whoes name is ...");
}
public void guardFarmBefore() {
System.out.println("XMLGuardian spotted a monkey is approaching the farm...");
}
public void guardFarmAfter(String name,int num,Object retVal) {
System.out.println("XMLGuardian caught a monkey stealling " + num + " corns whoes name is ..." + name );
}
}
XML配置:
[html] view
plain copy
<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="guardian" class="com.test.spring.aspectj.XMLGuardian" />
<bean id="monkey" class="com.test.spring.aspectj.Monkey" />
<aop:config>
<aop:aspect id="myAspect" ref="guardian">
<aop:pointcut id="guardOrchard"
expression="execution(* com.test.spring.aspectj.Monkey.stealPeaches(..))" />
<aop:before pointcut-ref="guardOrchard" method="guardOrchardBefore" />
<aop:after-returning pointcut-ref="guardOrchard" method="guardOrchardAfter"/>
<aop:pointcut id="guardFarm"
expression="execution(* com.test.spring.aspectj.Monkey.stealCorns(..))" />
<aop:before pointcut-ref="guardFarm" method="guardFarmBefore" />
<aop:after-returning pointcut="execution(* com.test.spring.aspectj.Monkey.stealCorns(..)) and args(name,num,..)" returning="retVal"
method="guardFarmAfter" />
<!-- arg-names="name1" -->
</aop:aspect>
</aop:config>
</beans>
客户端测试代码:
[java] view
plain copy
ApplicationContext context = new ClassPathXmlApplicationContext("conf/xmlaspectJAppcontext.xml");
Monkey monkey = (Monkey) context.getBean("monkey");
try {
monkey.stealPeaches("mighty monkey");
monkey.stealCorns("mighty monkey",3);
} catch (Exception e) {
}
运行结果:
[plain] view
plain copy
XMLGuardian spotted a monkey is approaching the orchard...
Monkey mighty monkey is stealling peaches...
XMLGuardian caught a monkey stealling peaches whoes name is ...
XMLGuardian spotted a monkey is approaching the farm...
Monkey mighty monkey is stealling corns...
XMLGuardian caught a monkey stealling 3 corns whoes name is ...mighty monkey
Spring AOP 只支持对bean的方法级的'切入',而且AOP的内部机制和AspectJ有所区别,Spring主要是通过动态代理来实现AOP,使用JDK的动态代理(如果被代理的bean是interface的话)或者CGLIB(如果如果被代理的bean不是interface的话).
一:使用AspectJ注解:
1,启用对AspectJ的支持:
通过在Spring的配置中引入下列元素来启用Spring对AspectJ的支持:
<aop:aspectj-autoproxy />
或者(如果不是使用XSD的话)
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
2,声明一个带有@Aspect注解的类,在这个类中声明那些方法需要被'关注'(利用@Pointcut),在那些时机点进行关注(利用@Before,@AfterReturning等等...),执行'切入'的方法
3,在Spring的配置文件中定义这个'切面'类:任意带有一个@Aspect切面(拥有@Aspect注解)的bean都将被Spring自动识别并用于配置在Spring AOP.
4,使用被Spring管理的bean,在执行被'关注'的方法时,'切入'的方法就会被执行.
一个完整的例子:
需要被'切入'的类:
[java] view
plain copy
public class Monkey {
public void stealPeaches(String name) {
System.out.println(" Monkey " + name + " is stealling peaches...");
}
public void stealCorns(String name) {
System.out.println(" Monkey " + name + " is stealling corns...");
}
}
'切面'类:
[java] view
plain copy
@Aspect
public class Guardian {
@Pointcut("execution(* com.test.spring.aspectj.Monkey.stealPeaches(..))")
public void guardOrchard() {
}
@Before(value = "guardOrchard()")
public void guardOrchardBefore() {
System.out.println("Guardian spotted a monkey is approaching the orchard...");
}
@AfterReturning("guardOrchard() && args(name,..)")
public void guardOrchardAfter(String name) {
System.out.println("Guardian caught a monkey stealling peaches whoes name is " + name + "...");
}
@Around("guardOrchard() && args(name,..)")
public void guardOrchardAround(ProceedingJoinPoint joinpoint,String name) {
System.out.println("Guardian guardOrchardAround started ... " + name);
try {
joinpoint.proceed();
} catch (Throwable e) {
System.out.println("Guardian guardOrchardAround exception happened ... " + name);
}
System.out.println("Guardian guardOrchardAround completed ... " + name);
}
@Pointcut("execution(* com.test.spring.aspectj.Monkey.stealCorns(..))")
public void guardFarm() {
}
@Before(value = "guardFarm()")
public void guardFarmBefore() {
System.out.println("Guardian spotted a monkey is approaching the farm...");
}
@AfterReturning("guardFarm() && args(name,..)")
public void guardFarmAfter(String name) {
System.out.println("Guardian caught a monkey stealling corns whoes name is " + name + "...");
}
}
配置文件:
[html] view
plain copy
<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!--
<aop:aspectj-autoproxy /> equals to <bean
class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"
/>
-->
<aop:aspectj-autoproxy />
<bean id="guardian" class="com.test.spring.aspectj.Guardian" />
<bean id="monkey" class="com.test.spring.aspectj.Monkey" />
</beans>
使用bean:
[java] view
plain copy
ApplicationContext context = new ClassPathXmlApplicationContext("conf/aspectJAppcontext.xml");
Monkey monkey = (Monkey) context.getBean("monkey");
try {
monkey.stealPeaches("mighty monkey");
monkey.stealCorns("mighty monkey");
} catch (Exception e) {
}
运行结果:
[plain] view
plain copy
Guardian spotted a monkey is approaching the orchard...
Guardian guardOrchardAround started ... mighty monkey
Monkey mighty monkey is stealling peaches...
Guardian caught a monkey stealling peaches whoes name is mighty monkey...
Guardian guardOrchardAround completed ... mighty monkey
Guardian spotted a monkey is approaching the farm...
Monkey mighty monkey is stealling corns...
Guardian caught a monkey stealling corns whoes name is mighty monkey...
二:通过XML配置AspectJ实现AOP:在java类中定义要被'方面'调用的切入方法,在XML中配置.
例子:被'切入'的类,普通java类:
[java] view
plain copy
public class Monkey {
public void stealPeaches(String name) {
System.out.println(" Monkey " + name + " is stealling peaches...");
}
public void stealCorns(String name,int numberToSteal) {
System.out.println(" Monkey " + name + " is stealling corns...");
}
}
定义要被'方面'调用的切入方法的类:
[java] view
plain copy
public class XMLGuardian {
public void guardOrchardBefore() {
System.out.println("XMLGuardian spotted a monkey is approaching the orchard...");
}
public void guardOrchardAfter() {
System.out.println("XMLGuardian caught a monkey stealling peaches whoes name is ...");
}
public void guardFarmBefore() {
System.out.println("XMLGuardian spotted a monkey is approaching the farm...");
}
public void guardFarmAfter(String name,int num,Object retVal) {
System.out.println("XMLGuardian caught a monkey stealling " + num + " corns whoes name is ..." + name );
}
}
XML配置:
[html] view
plain copy
<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="guardian" class="com.test.spring.aspectj.XMLGuardian" />
<bean id="monkey" class="com.test.spring.aspectj.Monkey" />
<aop:config>
<aop:aspect id="myAspect" ref="guardian">
<aop:pointcut id="guardOrchard"
expression="execution(* com.test.spring.aspectj.Monkey.stealPeaches(..))" />
<aop:before pointcut-ref="guardOrchard" method="guardOrchardBefore" />
<aop:after-returning pointcut-ref="guardOrchard" method="guardOrchardAfter"/>
<aop:pointcut id="guardFarm"
expression="execution(* com.test.spring.aspectj.Monkey.stealCorns(..))" />
<aop:before pointcut-ref="guardFarm" method="guardFarmBefore" />
<aop:after-returning pointcut="execution(* com.test.spring.aspectj.Monkey.stealCorns(..)) and args(name,num,..)" returning="retVal"
method="guardFarmAfter" />
<!-- arg-names="name1" -->
</aop:aspect>
</aop:config>
</beans>
客户端测试代码:
[java] view
plain copy
ApplicationContext context = new ClassPathXmlApplicationContext("conf/xmlaspectJAppcontext.xml");
Monkey monkey = (Monkey) context.getBean("monkey");
try {
monkey.stealPeaches("mighty monkey");
monkey.stealCorns("mighty monkey",3);
} catch (Exception e) {
}
运行结果:
[plain] view
plain copy
XMLGuardian spotted a monkey is approaching the orchard...
Monkey mighty monkey is stealling peaches...
XMLGuardian caught a monkey stealling peaches whoes name is ...
XMLGuardian spotted a monkey is approaching the farm...
Monkey mighty monkey is stealling corns...
XMLGuardian caught a monkey stealling 3 corns whoes name is ...mighty monkey
Spring AOP 只支持对bean的方法级的'切入',而且AOP的内部机制和AspectJ有所区别,Spring主要是通过动态代理来实现AOP,使用JDK的动态代理(如果被代理的bean是interface的话)或者CGLIB(如果如果被代理的bean不是interface的话).
相关文章推荐
- ASP.NET Core框架揭秘(持续更新中…)
- 在ASP.NET中如何运行后台任务
- ASP.NET Core "完整发布,自带运行时" 到jexus
- 【ASP】Window2008站点安全设置,IIS7/IIS7.5中目录执行权限的设置方法
- 使用 dotnet watch 开发 ASP.NET Core 应用程序
- asp.net mvc本地程序集和GAC的程序集冲突解决方法
- PiLC - S7 PLC for Raspberry Pi
- 树莓派 GrovePi Raspberry Pi 3B 添加 Grove Pi 扩展
- asp.net mvc 分页 CPager(秒杀杨涛MvcPager)之封装之后
- Asp.net Core基于MVC框架实现PostgreSQL操作
- FileUpload上传Excel文件,Aspose导入数据至数据库(web)
- ASP.NET 第一课后小结
- asp.net mvc 之旅 —— 第五站 从源码中分析asp.net mvc 中的TempData
- JavaSpring
- linq to entity查询的日期格式化
- ASP.NET的内置对象之四 Cookie
- asp.net mvc 分页 CPager(秒杀杨涛MvcPager)之封装之前
- ASP.NET MVC 基于角色的权限控制系统的示例教程
- ASP.NET Core "完整发布,自带运行时" 到jexus
- .NET开发人员必看:提高ASP.NET Web应用性能的24种方法和技巧