Spring配置方式实现Aop注解方式实现Aop Aop的概念

什么是Aop

是将项目中的方法素有的共通性的代码提取出来 形成一个切面类 直接插入到 方法中 形成了解耦 以及增加代码的左右 
 
 它可以不修改原有代码的情况 增强原有组件的功能
 将共同业务逻辑 提取到切面中 有利于 切面 和 组件 解耦 提供组件和切面的复用程度  提高程序灵活性。

AOP的概念

Aspect 切面 封装共通业务逻辑的 封装共通业务逻辑的类叫切面类 用切面类创建的
对象 叫切面对象。
JoinPoint 连接点 用来说明共通业务逻辑 所嵌入的位置 一般封装了方法的信息

PointCut   切点        多个连接点 组成的一个集合 (后面会讲用表达式来表达切点)

Target     目标        要加强的对象   

Proxy      代理        增强之后的对象  

Advice     通知        时机    目标方法调用之前   目标方法调用之后    目标方法调用前后  目标方法最终  
         目标方法出现异常



 切面  ---------   通知  ------------- 切点   

基于配置文件形式实现Aop

简单案例 在Serviec输出方法中 加入 输出时间的方法  不修改原有逻辑

service代码

@Service
public class TestService {
	
	
	public void test1(){
		System.out.println("123");
	}

	public void test2(){
		System.out.println("123");
	}
}

切面类代码 (增加代码)

public class TestAs {
	public void start(){
		System.out.println("********");
	}
}

配置文件 配置Aop 将 切面类插入方法 方法执行后执行切面类方法

<aop:config>
	<aop:aspect ref="testService "> 	//aop的归属类
		<aop:after method="start" pointcut="bean(testService )"/> //after 在插入方法之后   method 执行的方法    pointcut 插入的类
	</aop:aspect>
</aop:config>
<?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:context="http://www.springframework.org/schema/context" 
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
	xmlns:jee="http://www.springframework.org/schema/jee" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">
	//开启注解形式扫描
	<context:component-scan base-package="com.liheng"></context:component-scan>

	//将切面类加入到ioc容器中
	<bean id="as" class="com.test.as.TestAs"></bean>
	
	//配置 aop配置
	<aop:config>
		//aop的归属类
		<aop:aspect ref="testService ">
			//after 在插入方法之后   method 执行的方法    pointcut 插入的类
			<aop:after method="start" pointcut="bean(testService )"/>
		</aop:aspect>
	</aop:config>
</beans>


切点表达式的写法

bean限定

bean(bean对象在容器的id)   支持统配  如  *dao

类型限定表达式

within(类型限定)   表达式中最后一部分必须是类型

方法限定表达式

execution(方法限定表达式)
 	方法限定表达式的构成是      权限修饰   方法返回值类型   方法名(参数列表) throws  异常   
 	注意  方法返回值   方法名() 是必须的 其它可选
void   *Account()    

Spring 中的五种通知类型

	 <aop:before    前置通知        目标方法调用前执行 

 <aop:after     最终通知         目标方法调用后 肯定会执行 

 <aop:after-returning  后置通知    目标方法调用后 执行  

 <aop:after-throwing   异常通知    目标方法出现异常后执行  

 <aop:around           环绕通知     逻辑是整体时 推荐使用环绕通知 

注解形式实现Aop

在配置文件中开启标注形式Aop
开启组件扫描

案例 实现方法的异常日志

配置文件 配置Aop 注解形式
<aop:aspectj-autoproxy proxy-target-class=“true”></aop:aspectj-autoproxy>

proxy-target-class=“true” 默认是 false 是 sun公司开启代理 false是cglib公司

<?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:context="http://www.springframework.org/schema/context" 
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
	xmlns:jee="http://www.springframework.org/schema/jee" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">
	//开启注解方式
	<context:component-scan base-package="com.liheng"></context:component-scan>
	//开启mvc注解
	<mvc:annotation-driven></mvc:annotation-driven>
	//开启注解形式Aop
	<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
</beans>


Aop切面类实现

//将当前类加入到容器中
@Component
//将当前类设置为切面类
@Aspect
public class DaoAs {
	SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
	//在 testDao类所有方法执行前 执行此方法
	@Before("bean(testDao)")
	public void add(){
		System.out.println(sim.format(new Date()));
	}
	
	//当方法出现异常 输出时间 方法的名称 以及出现的异常 
	//throwing="e" 需要接收方法的异常 转换成e  e异常类
	//JoinPoint 可以接收到 方法的名称
	@AfterThrowing(pointcut="bean(testDao)",throwing="e")
	public void exceptionLog(JoinPoint pj,Exception e){
		System.out.println(sim.format(new Date())+"\\"+pj.getSignature()+"\\"+e);
	}
	
	
	//环绕通知 通过ProceedingJoinPoint 类可以执行 即将要调用的方法 返回的就是执行的方法需要将返回的方法Return
	
	@Around("execution(void *User())")
	public Object time(ProceedingJoinPoint pjj) throws Throwable{
		long startTime = System.currentTimeMillis();
		Object o = pjj.proceed();
		long endTime = System.currentTimeMillis();
		System.out.println(pjj.getSignature()+"执行"+(endTime-startTime)+"毫秒");
		return o;
	}

}


五种通知对应的标注

<aop:before 前置通知 目标方法调用前执行 @Before
<aop:after 最终通知 目标方法调用后 肯定会执行 @After
<aop:after-returning 后置通知 目标方法调用后 执行 @AfterReturning
<aop:after-throwing 异常通知 目标方法出现异常后执行 @AfterThrowing
<aop:around 环绕通知 逻辑是整体时 推荐使用环绕通知 @Around

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值