Spring之Spring AOP(JDK动态代理和CGLIB代理)

1.什么是AOP

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

2.AOP术语

程序流程图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.AOP动态代理
3.1JDK动态代理

局限性:使用动态代理的对象 ∗ ∗ 必 须 实 现 一 个 或 多 个 接 口 ∗ ∗ \color{red}{**必须实现一个或多个接口**}
在这里插入图片描述
UserDao接口

package com.lin.jdk;

public interface UserDao {

	public void addUser();
	public void deleteUser();
}

UserDaoImpl实现类

package com.lin.jdk;

//目标类
public class UserDaoImpl implements UserDao{

	@Override
	public void addUser() {
		System.out.println("添加用户!");
		
	}

	@Override
	public void deleteUser() {
		// TODO Auto-generated method stub
		System.out.println("删除用户!");
	}

}

MyAspect切面类

package com.lin.aspect;

//切面类:可以存在多个通知Advice(既增强的方法)
public class MyAspect {

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

JdkProxy类JDK的代理类 声明目标类接口

package com.lin.jdk;

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

import com.lin.aspect.MyAspect;

/**
 * JDK的代理类 声明目标类接口
 *
 */

public class JdkProxy implements InvocationHandler {

// 声明目标类接口
	private UserDao userDao;

	//创建代理方法
	public Object createProxy(UserDao userDao) {
		this.userDao=userDao;
		//1.需要得到一个类加载器
		ClassLoader classLoader=	JdkProxy.class.getClassLoader();
		//2.被代理对象实现所有接口
		Class<?>[] clazz=userDao.getClass().getInterfaces();
		//3.使用代理类进行增强,返回的是代理后的对象	
		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;
	}
}

测试类

package com.lin.jdk;

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

运行结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/2019070217073191.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDExNzI3Mg==,size_16,color_FFFFFF,t_70

3.2CGLIB代理

在这里插入图片描述

1.创建UserDao类(不是接口)

package com.lin.cglib;

public class UserDao {

	public void addUser() {
		System.out.println("添加用户");
	}
	public void deleteUser() {
		System.out.println("删除用户");
	}
}

MyAspect切面类

package com.lin.aspect;

//切面类:可以存在多个通知Advice(既增强的方法)
public class MyAspect {

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

创建 CglibProxy类

package com.lin.cglib;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import com.lin.aspect.MyAspect;

public class CglibProxy implements MethodInterceptor {
//代理方法
	public Object createProxy(Object target) {
		//创建一个动态类对象
		//Enhancer是CGlib的核心类
		Enhancer enhancer=new Enhancer();
		//确定需要增强的类,设置其父类
		enhancer.setSuperclass(target.getClass());
		//添加回调函数 MethodInterceptor extends org.springframework.cglib.proxy.Callback
		enhancer.setCallback(this);
		//返回创建的代理类
		return enhancer.create();
		
	}
	/**
	 * proxy:CGlib根据制定父类生成的代理对象
	 * method 拦截方法
	 * args :拦截的方法的参数数组
	 * methodProxy:方法的代理对象,用于执行父类的方法
	 * 
	 * 
	 */
	//intercept在程序执行目标方法时被调用
	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		//创建切面对象
		MyAspect myAspect=new MyAspect();
		//前增强
		myAspect.check_Permissions();
		//目标方法执行
		Object obj=methodProxy.invokeSuper(proxy, args);
		//后增强
		myAspect.log();
		
		return obj;
	}

}

测试类CglibTest

package com.lin.cglib;

public class CglibTest {
	public static void main(String[] args) {
		//创建代理对象
		CglibProxy cglibProxy=new CglibProxy();
		//创建目标对象
		UserDao userDao=new UserDao();
		
		//获取增强后的目标对象
	UserDao userDao1=	(UserDao) cglibProxy.createProxy(userDao);
		//执行方法
	userDao1.addUser();
	userDao1.deleteUser();
		
	}
}

运行结果:
和JDK动态代理一样
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值