Spring之AOP之底层实现

2019-12-31 15:04:39 浏览数 (1)

文章目录

  1. 1. Spring之AOP之底层实现
    1. 1.1. 静态代理实现
    2. 1.2. 动态代理实现
    3. 1.3. 参考文档

Spring之AOP之底层实现

静态代理实现

  • 定义IStudnetService接口
代码语言:javascript复制
/**
 * IStudentService的接口
 * @author chenjiabing
 */
public interface IStudentService {

	void add();
}
  • 定义StudentServiceImpl实现方法
代码语言:javascript复制
@Service
public class StudentServiceImpl implements IStudentService {

	public void add() {
		System.out.println("StudentService的add方法");
	}
}
  • 定义StudentAop切面类
代码语言:javascript复制
/**
 * 切面类
 * @author chenjiabing
 */
@Component
public class StudentAOP {
	//之前执行
	public void before(){
		System.out.println("StudentAOP.before....");
	}
	
	//之后执行
	public void after(){
		System.out.println("StudentAOP.after");
	}
	
	//在之后执行,只在没有出现异常的时候执行
	public void afterReturning(){
		System.out.println("StudentAOP.afterReturning");
	}
	
	//之后执行,但是只在出现异常的时候执行
	public void afterThrowing(){
		System.out.println("StudentAOP.throwing");
	}
	
	//环绕方法
	public void arounding(){
		System.out.println("StudentAOP.arounding");
	}
}
  • 定义StudentProxy代理类
代码语言:javascript复制
/**
 * 静态代理类
 * @author chenjiabing
 */
@Component
public class StudentProxy implements IStudentService {
	@Resource
	private StudentAOP studentAOP;   //依赖注入切面对象
	@Resource
	private IStudentService studentService;  //目标对象
	
	public void add() {
		try {
			studentAOP.arounding();  //执行环绕方法
			studentAOP.before();  //执行切面类的方法
			studentService.add();  //执行目标对象的方法
			studentAOP.after();  //执行切面的after方法
			studentAOP.afterReturning();  //执行切面类afterReturning的方法
		} catch (Exception e) {
			studentAOP.afterThrowing();  //执行切面类的方法,在出现异常之后执行
		}finally{
			studentAOP.arounding();  //执行环绕方法
		}
	}
}
  • 测试方法
代码语言:javascript复制
@Test
public void test1() {
	// 加载Spring的配置文件
	AbstractApplicationContext ac = new ClassPathXmlApplicationContext(
			"spring-dao.xml", "spring-service.xml","spring-aop.xml");
	
	//创建Service,其中使用的是动态代理类
	IStudentService studentService=ac.getBean("studentProxy",IStudentService.class);
	studentService.add();
}

动态代理实现

  • 代理类实现java.lang.reflect.InvocationHandler接口
代码语言:javascript复制
/**
 * 动态代理的类
 * 
 * @author chenjiabing
 */
@Component   // 创建对象
public class ProxyHandler implements InvocationHandler {
	
	private Object object; // 目标对象
	
	@Resource
	private StudentAOP studentAOP; // 注入切面类

	// 获取动态代理类的对象
	public Object getObject(Object object){
		this.object=object;
		/**
		 * 第一个参数:目标类的类加载器
		 * 第二个参数:目标类的接口
		 * 第三个参数:动态代理的实例
		 */
		return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
	}

	/**
	 * @param proxy :被代理的对象
	 * @param method : 要调用的方法
	 * @param args : 方法调用的时候所需要的参数
	 */
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		
		studentAOP.before();  //调用切面的before方法
		
		//通过反射调用目标类的方法
		Object result=method.invoke(object, args);  //调用目标类的方法
		studentAOP.after();  //调用切面的after方法
		
		return result;
	}

}
  • 测试方法
代码语言:javascript复制
@Test
public void test2() {
	// 加载Spring的配置文件
	AbstractApplicationContext ac = new ClassPathXmlApplicationContext(
			"spring-dao.xml", "spring-service.xml","spring-aop.xml");
	
	//获取动态代理类的对象
	ProxyHandler proxyHandler=ac.getBean("proxyHandler",ProxyHandler.class);
	
	//获取代理类的对象
	IStudentService studentService=(IStudentService) proxyHandler.getObject(new StudentServiceImpl());
	studentService.add();
	
}

参考文档

  • JDK代理和Cglib代理的实现

0 人点赞