Spring 8 AspectJ对AOP的实现

1 AspectJ:面向切面的框架,定义了AOP语法,有一个专门的编译器用来生成遵守Java字节码规范的class文件

2 AspectJ 的通知类型
常用的有五种
前置通知,后置通知,环绕通知,异常通知,
最终通知(无论程序是否运行正常必执行,类似于try catch中的finally代码块)

3 切入点表达式
定义了专门的表达式用于指定切入点,表达式原型

execution (  [modifiers-pattern]   访问权限类型
					ret-type-pattern     返回值类型
					[declaring-type-pattern]    全限定性类名
					name-pattern(param-pattern)  方法名(参数名)
					[throws-pattern]    抛出异常类型
)

举例
execution  (public * * {..})
指定切入点为任意 公共 方法
execution  (* set * {..})
指定切入点为任何一个以“set”开始的方法
execution  (* com.cj.service.* .*  {..})
指定切入点为service包里的任意类的任意方法
execution   (* com.cj.service..* .*  {..})
指定切入点为service包及其子包里的任意类的任意方法,“..”出现在类名中时后必须跟“*”,表示包和子包下的所有类
execution   (* com.cj.service.IService .*  {..})
IService 接口中的任意方法
execution   (* com.cj.service.IService+ .*  {..})
IService若为接口,则为IService 接口中的任意方法及其实现类的方法;若为类,则为该类及其子类任意方法
execution   (* hello(String,int))
所有hello(String,int)方法,非lang包下的类作为参数需写全限定类名,例如hello(java.util.List,int)
execution   (* hello(String,*))
所有hello(String,*)方法,参数支持通配符

4 AspectJ的开发环境
需要AOP环境+com.springsource.org.aspectj.weaver.jar (+com.springsource.org.aspectj.tools.jar)
AOP环境,引入AOP约束

5 AspectJ 基于注解的AOP实现 前置通知
(1)实现步骤
step1:定义业务接口和实现类

public  interface IUserService{
		//主业务方法
		void doSome();
		//主业务方法
		void doOther(int a,String b);
		//主业务方法
		String doThird();
}

step2 :定义切面POJO类

step3:在切面上添加@Aspect注解

@Aspect   //表示当前POJO类为切面
public class MyAspect{//POJO类
	@Before("execution(* *..IUserService.doSome(..))")    //用(..)可支持有参与无参方法,更好
	public void myBefore(){
		System.out.println("执行前置通知方法");
	}
	
	@Before("execution(* *..IUserService.doThird(..))")    //用(..)可支持有参与无参方法,更好
	public void myBefore(JoinPoint jp){
		System.out.println("执行前置通知方法===+jp;"+jp);//JoinPoint为切入点表达式
	}
}

step4:在POJO类的普通方法上添加注解

step5:注册目标对象与POJO类

	目标对象
	<bean id="userService" class="com.cj.service.UserServiceImpl"/>
	切面
	<bean id="myAspect" class="com.cj.aspect.MyAspect"/>

step6:注册AspectJ的自动代理

	AspectJ的自动代理
	<aop:aspectj-autoproxy/>

step7:测试类中使用目标对象的id

	@Test
	public void test01(){
		//创建容器
		String resource = "applicationContext.xml";
		ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
		IUserService userService = (IUserService) ac.getBean("userService");
		service.doSome();
	}

后置通知

@AfterReturning("execution(* *..IUserService.doSecond(..))")  
public void myAfter(JoinPoint jp){
	System.out.println("执行后置通知方法===+jp;"+jp);//JoinPoint为切入点表达式
}
@AfterReturning(value="execution(* *..IUserService.doThird(..))",returning="result")  //doThird有返回值
public void myAfter(Object result){
	System.out.println("执行后置通知方法===+result;"+result);//JoinPoint为切入点表达式
}

环绕通知

@Around("execution(* *..IUserService.doSecond(..))")  
public Object myAroundr(ProceedJoinPoint pjp) throws Throwable{
	System.out.println("执行环绕通知方法之前===+pjp;"+pjp);
	Object result = pjp.proceed();
	System.out.println("执行环绕通知方法之后===+pjp;"+pjp);
	return result;
}

异常通知

@AfterThrowing("execution(* *..IUserService.doSecond(..))")  
public void myAfterThrowing(){//监控指定目标方法执行是否发生异常
	System.out.println("执行异常通知方法===+");//JoinPoint为切入点表达式
}
@AfterThrowing(value="execution(* *..IUserService.doSecond(..))",throwing="ex")  
public void myAfterThrowing(Exception ex){//监控指定目标方法执行是否发生异常
	System.out.println("执行异常通知方法===+ex::::"ex.getMessage());/打印异常信息
}

最终通知

@After("execution(* *..IUserService.doSome(..))")  
public void myAfter(){
	System.out.println("执行最终通知方法myAfter();");//最终通知在后置前执行
}

定义切入点(切入点冗余)

@Pointcut("execution(* *..IUserService.doSome(..))")
private void doSomePointcut(){}
@After("doSomePointcut()")  
public void myAfter(){
	System.out.println("执行最终通知方法myAfter();");//最终通知在后置前执行
}

6 AspectJ 基于xml的AOP实现 (常用)
前置通知

//POJO类,定义切面
public class MyAspect{
	public void myBefore(){
		System.out.println("执行前置通知方法");
	}
	public void myBefore(){
		System.out.println("执行前置通知方法===");
	}
}

目标对象
<bean id="userService" class="com.cj.service.UserServiceImpl"/>
切面
<bean id="myAspect" class="com.cj.aspect.MyAspect"/>

AOP配置
<aop:config>
		(aspect,pointcut,advisor)
		<aop:pointcut expression="execution()" id="doSomePointCut"/>
		<aop:aspect ref="myAspect">
				<aop:before method="myBefore" point-ref="doSomePointCut"/>
				<aop:before method="myBefore(全限定参数名例如org.aspect.lang.JoinPoint)" point-ref="doSomePointCut"/>
		</aop:aspect>
</aop:config>

其他通知与其类似,名称参数与注解类似

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值