Spring Aop实现




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/


aspect


j/*.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()==========="); 
}


}


软件工程师速成系列之Spring AOP
Spring Aop的思...AOP的基本概念

测试服务类:

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/txxsi:schemaLocation="http://www.springframework.org/schema/beanshttp://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) 


注:来自百度文档、内容仅供个人学习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值