SpringAOP原理

主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。
主要的意图是:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。
SpringAOP原理_java学习

SpringAOP原理_java学习_02

jdk动态代理和CGLIB的区别:
jdk动态代理需要接口,基于反射实现
cglib是基于ASM字节码包装的一个类库

接下来我们一起来看一个aop案例:
新建一个maven project,导入如下依赖信息:

<dependencies>
		<!-- 引入Spring-AOP等相关Jar -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>3.0.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>3.0.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>3.0.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>3.0.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>1.6.1</version>
		</dependency>
		<dependency>
			<groupId>aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.5.3</version>
		</dependency>
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>2.1_2</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
		<dependency>
			<groupId>com.mchange</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.5.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.37</version>
		</dependency>
	</dependencies>

然后新建一个UserService接口

package com.itmayiedu.service;
public interface UserService {
   public void add();
}

再写实现类

package com.itmayiedu.service.impl;
import org.springframework.stereotype.Service;
import com.itmayiedu.service.UserService;
@Service
public class UserServiceImpl  implements UserService{
	public void add() {
		System.out.println("开始往数据库中写数据");	
	}
}

然后还要把spring.xml文件导入
aop:aspectj-autoproxy</aop:aspectj-autoproxy> 的作用是开启aop注解 (也就是说可以使用@before,@after,@around等注解在我们的代码中)
SpringAOP原理_java学习_03
接下来开始写切面类:

package com.itmayiedu.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class AopLog {
 // aop 编程里面有几个通知: 前置通知 后置通知 运行通知 异常通知 环绕通知
    @Before("execution(* com.itmayiedu.service.UserService.add(..))")
    public void before(){
    	System.out.println("前置通知");
    }
     // 后置通知 在方法运行后执行
    @After("execution(* com.itmayiedu.service.UserService.add(..))")
    public void after(){
    	System.out.println("后置通知");
    }
    // 运行通知(当调用方法执行完毕之后在执行,但是在后置通知之后执行)
    @AfterReturning("execution(* com.itmayiedu.service.UserService.add(..))")
    public void afterReturn(){
    	System.out.println("运行通知");
    }
    / /异常通知
    @AfterThrowing("execution(* com.itmayiedu.service.UserService.add(..))")
    public void afterThrowing(){
    	System.out.println("异常通知");
    }
     // 环绕通知 在方法之前和之后处理事情
    @Around("execution(* com.itmayiedu.service.UserService.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
    // 调用方法之前执行
    	System.out.println("环绕通知开始");
    	proceedingJoinPoint.proceed();// 代理调用方法 注意点: 如果调用方法抛出溢出不会执行后面代码
   // 调用方法之后执行
    	System.out.println("环绕通知结束");  	
    }    
}

最后编写一个测试类Test01来测试aop效果:

package com.itmayiedu.service;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test01 {
public static void main(String[] args) {
	ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
	UserService userService = (UserService) applicationContext.getBean("userServiceImpl");
	userService.add();
}
}

运行效果如下:(一定要记得几个通知的顺序)
SpringAOP原理_java学习_04