SpringAOP之JDK动态代理

一.什么是AOP?

AOP简介

AOP的全称是Aspect-Oriented Programming,即面向切面编程(也称面向方面编程)。它是面向对象编程(OOP)的一种补充,目前已成为一种比较成熟的编程方式。

AOP采取横向抽取机制,将分散在各个方法中的重复代码提取出来,然后在程序编译或运行时,再将这些提取出来的代码应用到需要执行的地方。这种采用横向抽取机制的方式,采用传统的OOP思想显然是无法办到的,因为OOP只能实现父子关系的纵向的重用。虽然AOP是一种新的编程思想,但却不是OOP的替代品,它只是OOP的延伸和补充。

AOP术语

Aspect:封装的用于横向插入系统功能(如事务、日志等)的类

Joinpoint:在程序执行过程中的某个阶段点

Pointcut:切面与程序流程的交叉点,即那些需要处理的连接点

Proxy(代理):将通知应用到目标对象之后,被动态创建的对象

Weaving(织入):将切面代码插入到目标对象上,从而生成代理对象的过程。

二.动态代理

1.jdk动态代理

JDK动态代理是通过java.lang.reflect.Proxy 类来实现的,我们可以调用Proxy类的newProxyInstance()方法来创建代理对象。对于使用业务接口的类,Spring默认会使用JDK动态代理来实现AOP。

类和工具包

SpringAOP之JDK动态代理_第1张图片SpringAOP之JDK动态代理_第2张图片SpringAOP之JDK动态代理_第3张图片SpringAOP之JDK动态代理_第4张图片

控制台打印输出

SpringAOP之JDK动态代理_第5张图片

 

UserDao.java

package com.itheima.jdk;

/**
 * 该类为接口类
 * */
public interface UserDao {

	/*添加方法,删除方法*/
	public void addUser();
	public void deleteUser();
}

UserDaoImpl.java

package com.itheima.jdk;

/**
 *该类为接口实现类
 * */
public class UserDaoImpl implements UserDao{

	/*继承接口UserDao,并实现UserDao内的方法*/
	@Override
	public void addUser() {
		
		System.out.println("添加用户");
	}

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

	
}

MyAspect.java

package com.itheima.aspect;
/**
 * 该类为切面类
 * 并在该类中定义一个模拟检查的方法,和一个模拟记录日志的方法
 * 用这两个方法,表示切面的通知
 * */
public class MyAspect {

	//模拟权限检查
	public void check_Permissions() {
		System.out.println("模拟权限检查");
	}
	//模拟记录日日志
	public void log() {
		System.out.println("模拟记录日志");
	}
}

JdkProxy.java

package com.itheima.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import com.itheima.aspect.MyAspect;

/**
 * Jdk代理类,该类实现InvocationHandler接口
 * 并编写代理方法
 * 在代理方法中需要通过Proxy类实现动态代理
 * */
public class JdkProxy implements InvocationHandler {
//声明接口类接口
	public UserDao userDao;
	//创建代理方法
	public Object createProxy(UserDao userDao) {
		this.userDao = userDao;
		//获取类加载器
		ClassLoader classLoader = JdkProxy.class.getClassLoader();
		//创建类数组,得到接口类的方法
		Class[] clazz = userDao.getClass().getInterfaces();
		return Proxy.newProxyInstance(classLoader, clazz, this);
	}
	/**
	 * 所有动态代理类的方法调用,都交给invoke()方法去处理
	 * proxy被代理对象
	 * method 将要被执行方法的信息(反射)
	 * args执行方法时所需参数
	 * */
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//声明切面
		MyAspect myAspect = new MyAspect();
		//调用模拟权限检查
		myAspect.check_Permissions();
		
		//调用方法,传入参数,并反射
		Object obj = method.invoke(userDao, args);
		
		//模拟记录日志
		myAspect.log();
		
		
		return obj;
	}

}

JdkTest.java

package com.itheima.jdk;

/**
 * 该类为测试类
 * */
public class JdkTest {

	public static void main(String[] args) {
		//创建代理对象
		JdkProxy jdkProxy = new JdkProxy();
		//创建被代理目标对象
		UserDao userDao = new UserDaoImpl();
		//从代理对象中,获取增强后的被代理目标对象
		UserDao userDao2 =(UserDao) jdkProxy.createProxy(userDao);
		//执行方法
		userDao2.addUser();
		userDao2.deleteUser();
	}

}

 

实现效果

SpringAOP之JDK动态代理_第6张图片

 

 

你可能感兴趣的:(SpringAOP)