spring的AOP(四)----Spring AOP 编程(Advisor)

Spring AOP增强类型
AOP联盟为通知Advice定义了org.aopalliance.aop.Interface.Advice
Spring按照通知Advice在目标类方法的连接点位置,可以分为5类
1.前置通知 org.springframework.aop.MethodBeforeAdvice 在目标方法执行前实施增强
2.后置通知 org.springframework.aop.AfterReturningAdvice 在目标方法执行后实施增强
3.环绕通知 org.aopalliance.intercept.MethodInterceptor 在目标方法执行前后实施增强
4.异常抛出通知 org.springframework.aop.ThrowsAdvice 在方法抛出异常后实施增强
5.引介通知 org.springframework.aop.IntroductionInterceptor 在目标类中添加一些新的方法和属性

Spring 支持AOP编程两种: 传统AOP(spring1.x) 和 AspecJ框架支持(spring2.0之后 )
基本上企业都是使用AspectJ 实现AOP 编程

通过execution函数定义切点表达式

通过execution函数,可以定义切点的方法切入
语法:
execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
例如
匹配所有类public方法  execution(public * *(..))
匹配指定包下所有类方法 execution(* cn.itcast.dao.*(..)) 不包含子包
execution(* cn.itcast.dao..*(..))  ..*表示包、子孙包下所有类
匹配指定类所有方法 execution(* cn.itcast.service.UserService.*(..))
匹配实现特定接口所有类方法 
	execution(* cn.itcast.dao.GenericDAO+.*(..))
匹配所有save开头的方法 execution(* save*(..))

开发步骤:
第一步: 在Spring 配置文件中,存在目标Bean
第二步: 传统Spring AOP 切面 Advisor (一个切点 和 一个通知增强)
第三步: 通过配置,实现advice 的 织入

代码示例:
CustomerDao.java

package com.my.advisor;

//业务接口
public interface CustomerDao {
	
	public void save();
	public void delete();
	public void update();

}

CustomerDaoImpl.java

package com.my.advisor;

public class CustomerDaoImpl implements CustomerDao {

	@Override
	public void save() {
		System.out.println("添加客户");
	}

	@Override
	public void delete() {
		System.out.println("删除客户");
	}

	@Override
	public void update() {
		System.out.println("修改客户");
	}

}


MyAroundAdvice.java

package com.my.advisor;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

//自定义环绕通知类 
public class MyAroundAdvice implements MethodInterceptor {

	//通过 methodInvocation 调用真实目标对象的方法
	@Override
	public Object invoke(MethodInvocation methodInvocation) throws Throwable {
		long begin = System.currentTimeMillis();
		
		// 执行目标对象的方法
		Object result = methodInvocation.proceed();
		
		long end = System.currentTimeMillis();
		System.out.println(methodInvocation.getMethod().getName()+ "目标方法运行时间:" + (end-begin));
		
		return result;
	}

}

applicationContext.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"
       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">
	
	<!-- 目标对象 -->
	<bean id="customerDao" class="com.my.advisor.CustomerDaoImpl" />
	
	<!-- 增强对象 -->
	<bean id="myAroundAdvice" class="com.my.advisor.MyAroundAdvice"></bean>
	
	<!-- 进行AOP配置 -->
	<!--  proxy-target-class="false" 是默认值,优先对接口代理(JdkProxy),没有接口,对类代理 (CglibProxy)-->
	<!--  proxy-target-class="true" 强制要求对类进行代理  -->
	<aop:config proxy-target-class="false">
		<!-- 定义切点  id是唯一标识,expression 切点表达式 -->
		<aop:pointcut expression="execution(* com.my.advisor.CustomerDaoImpl.save(..))" id="mypointcut"/>
		<!-- 传统意义上Spring AOP 切面支持 一个切点 和 一个通知 -->
		<aop:advisor advice-ref="myAroundAdvice" pointcut-ref="mypointcut"/>
	</aop:config>
	
	
</beans>

Test.java

package com.my.advisor;

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class Test {
	
	@Autowired
	@Qualifier("customerDao")
	private CustomerDao customerDao;
	
	@org.junit.Test
	public void demo(){
		customerDao.save();
		customerDao.update();
		customerDao.delete();
	}
	

}

运行结果:
proxy-target-class=“false” 是默认值,优先对接口代理(JdkProxy),没有接口,对类代理 (CglibProxy),其运行结果如下:
这里写图片描述

proxy-target-class=“true” 强制要求对类进行代理,其与运行结果如下:
这里写图片描述

对比两个运行结果可以发现,spring对接口进行的代理其性能要优于对类进行的代理。

Coding Diary

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值