Spring Aop实现——Annotation方式(注解式)
一、spring依赖库
* SPRING_HOME/dist/spring.jar
* SPRING_HOME/lib/jakarta-commons/commons-logging.jar
* SPRING_HOME/lib/log4j/log4j-1.2.14.jar
* SPRING_HOME/lib/aspectj/*.jar
二、编写切面aspect类
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
/**
* 定义切面
* @author
*
*/
@Aspect
public class CheckAspect {
/**
* 定义切入点(Pointcut),Pointcut的名称就是allSaveMethod, 此方法不能有参数和返回值,仅是个标识。
* Pointcut的内容——"execution(*, save*(..))", 是个表达式, 描述哪些对象的哪些方法(订阅Joinpoint)
*
*/
@Pointcut("execution(* save*(..)) || execution(* del*(..))")
private void allSaveMethod(){};
/*
* 定义通知advice(before型),标识在哪个切入点(allSaveMethod),织入(weaver)此方法
*/
@Before("allSaveMethod()")
public void checkUser(){
System.out.println("=======CheckAspect.checkUser()===========");
}
}
测试服务类:
public class UserManagerImpl implements IUserManager {
public void delUser(int id) {
System.out.println("=====UserManagerImpl.delUser()===========");
}
public String findUser(int id) {
System.out.println("=====UserManagerImpl.findUser()===========");
return null;
}
public void saveUser(String username, String password) {
System.out.println("=====UserManagerImpl.saveUser()===========");
}
public void updateUser(int id) {
System.out.println("=====UserManagerImpl.updateUser()===========");
}
}
三、applicationContext.xml中开启aop,配置相关切面aspect类
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
>
<!-- 启用aop -->
<aop:aspectj-autoproxy/>
<!--配置aspect-->
<bean id="checkAspect" class="com.CheckAspect" />
<bean id="userManager" class="com.manager.impl.UserManagerImpl" />
</beans>
四、测试用例:
public void testAspect(){
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
IUserManager userManager = (IUserManager) factory.getBean("userManager");//生成的代理类proxy
userManager.saveUser("cat", "123");
userManager.delUser(1);
userManager.updateUser(1); //没有调用切面advice,因为方法update与之不匹配。
}
执行结果:
=======CheckAspect.checkUser()===========
=====UserManagerImpl.saveUser()===========
=======CheckAspect.checkUser()===========
=====UserManagerImpl.delUser()===========
=====UserManagerImpl.updateUser()===========
=======================================
Schema-based式(xml配置)
一、类:
/**
* 定义切面
* @author dell
*
*/
public class CheckAspect {
/*
* 定义通知advice(before型),标识在哪个切入点(allSaveMethod),织入(weaver)此方法
*/
public void checkUser(){
System.out.println("=======CheckAspect.checkUser()===========");
}
}
二、applicationcontex.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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
>
<bean id="checkAspect" class="com.CheckAspect" />
<bean id="userManager" class="com.manager.impl.UserManagerImpl" />
<aop:config>
<!-- 配置切面appect , ref切面类 -->
<aop:aspect id="check" ref="checkAspect">
<!-- 配置切入点pointcut, 定义一个表达式 -->
<aop:pointcut id="allSaveMethod" expression="execution(* com.manager.impl.UserManagerImpl.save*(..))"/>
<!-- 设置before advice, 用checkAspect中的一个方法,并定位到相位的切入点pointcut -->
<aop:before method="checkUser" pointcut-ref="allSaveMethod"/>
</aop:aspect>
</aop:config>
</beans>
三、测试用例:
public void testAspect(){
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
IUserManager userManager = (IUserManager) factory.getBean("userManager");
userManager.saveUser("cat", "123");
userManager.delUser(1);
userManager.updateUser(1);
}
输出结果:
=======CheckAspect.checkUser()===========
=====UserManagerImpl.saveUser()===========
=====UserManagerImpl.delUser()===========
=====UserManagerImpl.updateUser()===========
四、Advice中可以加入JoinPoint参数,内含有代理类的方法的方法名和参数数组
import org.aspectj.lang.JoinPoint;
/*
* 定义通知advice(before型),标识在哪个切入点(allSaveMethod),织入(weaver)此方法
* JoinPoint 内含代理类的参数和方法
*/
public void checkUser(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
for(int i=0; i<args.length; i++){
System.out.println("参数" + i + "=" + args[i]);
}
System.out.println("代理类的方法:" + joinPoint.getSignature().getName());
System.out.println("=======CheckAspect.checkUser()===========");
}
输入结果:
参数0=cat
参数1=123
代理类的方法:saveUser
=======CheckAspect.checkUser()===========
=====UserManagerImpl.saveUser()===========
=====UserManagerImpl.delUser()===========
=====UserManagerImpl.updateUser()===========
=======================================
注:Aspect默认情况下不用实现接口,但对于目标对象(UserManagerImpl.java),在默认情况下必须实现接口;
如果没有实现接口必须引入CGLIB库
==================================
Spring AOP 用户可能会经常使用 execution
pointcut designator。执行表达式的格式如下:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
除了返回类型模式(上面代码片断中的ret-type-pattern),名字模式和参数模式以外,所有的部分都是可选的。 返回类型模式决定了方法的返回类型必须依次匹配一个连接点。 你会使用的最频繁的返回类型模式是 *
,它代表了匹配任意的返回类型。 一个全称限定的类型名将只会匹配返回给定类型的方法。名字模式匹配的是方法名。 你可以使用 *
通配符作为所有或者部分命名模式。 参数模式稍微有点复杂:()
匹配了一个不接受任何参数的方法, 而 (..)
匹配了一个接受任意数量参数的方法(零或者更多)。 模式 (*)
匹配了一个接受一个任何类型的参数的方法。 模式 (*,String)
匹配了一个接受两个参数的方法,第一个可以是任意类型,第二个则必须是String类型。 请参见AspectJ编程指南的 Language Semantics 部分。
下面给出一些常见切入点表达式的例子。
-
任意公共方法的执行:
execution(public * *(..))
-
任何一个以“set”开始的方法的执行:
execution(* set*(..))
-
AccountService
接口的任意方法的执行:
execution(* com.xyz.service.AccountService.*(..))
-
定义在service包里的任意方法的执行:
execution(* com.xyz.service.*.*(..))
-
定义在service包或者子包里的任意方法的执行:
execution(* com.xyz.service..*.*(..))
-
在service包里的任意连接点(在Spring AOP中只是方法执行) :
within(com.xyz.service.*)
-
在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) :
within(com.xyz.service..*)
-
实现了 AccountService
接口的代理对象的任意连接点(在Spring AOP中只是方法执行) :
this(com.xyz.service.AccountService)
-
实现了 AccountService
接口的目标对象的任意连接点(在Spring AOP中只是方法执行) :
target(com.xyz.service.AccountService)
-
任何一个只接受一个参数,且在运行时传入的参数实现了 Serializable
接口的连接点 (在Spring AOP中只是方法执行)
args(java.io.Serializable)
请注意在例子中给出的切入点不同于 execution(* *(java.io.Serializable))
: args只有在动态运行时候传入参数是可序列化的(Serializable)才匹配,而execution 在传入参数的签名声明的类型实现了 Serializable
接口时候匹配。
-
有一个 @Transactional
注解的目标对象中的任意连接点(在Spring AOP中只是方法执行)
@target(org.springframework.transaction.annotation.Transactional)
-
任何一个目标对象声明的类型有一个 @Transactional
注解的连接点(在Spring AOP中只是方法执行)
@within(org.springframework.transaction.annotation.Transactional)
-
任何一个执行的方法有一个 @Transactional
annotation的连接点(在Spring AOP中只是方法执行)
@annotation(org.springframework.transaction.annotation.Transactional)
-
任何一个接受一个参数,并且传入的参数在运行时的类型实现了 @Classified
annotation的连接点(在Spring AOP中只是方法执行)
@args(com.xyz.security.Classified)
相关推荐
Spring AOP配置的实例,最基本的Spring AOP配置
springAOP配置实现动态代理,有利于熟悉动态代理原理,深入了解spring。
SpringAop面向切面编程
Spring之AOP配置文件详解.txt Spring之AOP配置文件详解.txt 帮助你更快张握Java的学习!
Spring AOP配置事务方法,描述了spring的事务配置,方便开发应用和数据库的连接管理。
使用Spring配置文件实现AOP
里面包含了多种Spring AOP配置,十分详细。
利用SPring AOP配置切面的一个例子.
最近使用了springAOP编程,文档里面包含了springAOP的代码示例及详细注释说明,使用的是注解配置模式
SpringAop xml方式配置通知
Spring AOP 几个不同使用方法的完整例子,使用Junit4c测试, 在我的博客上有不同配置组合的说明,可以参考
SpringAOP的注解配置完成切面的编程,完成execution,annotation两种表达式的实例Ddemo
spring aop配置常用jar包,但是spring官网不提供下载。
基于注解配置和使用spring AOP(spring mvc框架)
Spring aop 配置 Spring aspect 配置 Spring advisor 配置 Spring pointcut 配置
Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供...
springIOC与AOP配置
@Component("userService")等价于在spring配置文件中定义一个<bean id="userService"/> @Resource(name="userDAO")将userDA注入进来 写一个拦截器的类 package com.spring.aop; import org.springframework....
一个基于配置文件的Spring AOP的实现。实现了前置通知,后置通知,以及拦截器的功能,配置中有详细的注释。