【Spring学习之路】2-2 AOP手动代理(一)JDK动态代理

什么是动态代理

基本原理

动态代理使用一个代理对象将对象包装起来,然后用该代理对象取代原始对象,任何对原始对象的调用都要通过代理,代理对象决定是否以及何时将方法调用转到原始对象上。
——————————————————————————————————————————————————————
(我是百度百科搬运工~~稍加修改和强调)

Java动态代理类位于Java.lang.reflect包(所以动态代理过程是涉及反射知识的)下,一般主要涉及到以下两个类:
动态代理的关键就两个东西:InvocationHandler和Proxy,实现这两个就基本实现动态代理啦!
一、Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method,Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组。这个抽象方法在代理类中动态实现。

二、Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容:

Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。

Static Class getProxyClass (ClassLoader loader,Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。

Static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。

Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。

为什么要使用动态代理

简言之,为了避免代码混乱和代码分散。

动态代理过程——直接代码讲解代理过程

  1. 接口:UserService
  2. 接口实现类:UserServiceImpl
  3. 代理类:MyBeanFactory
  4. 测试类:TestJDK

1.接口UserService:

//接口类
public interface UserService {
    //接口中定义三个方法
	public void addUser();
	public void updateUser();
	public void deleteUser();
	
}

2.接口实现类UserServiceImpl:

//接口实现类
public class UserServiceImpl implements UserService {

	@Override
	public void addUser() {
		System.out.println("a_proxy.a_jdk addUser");

	}

	@Override
	public void updateUser() {
		System.out.println("a_proxy.a_jdk updateUser");

	}

	@Override
	public void deleteUser() {
		System.out.println("a_proxy.a_jdk deleteUser");

	}

}

3.代理类(重点内容)MyBeanFactory,实现InvocationHandler接口:

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


//代理类实现InvocationHandler接口
public class MyBeanFactory implements InvocationHandler {

	//把真实提供服务的对象--UserService包含进代理类里
	private UserService userService;
	
	//构造函数
	public MyBeanFactory(UserService userService){
		super();
		this.userService=userService;
	}
	
	//第一步:增强过程  InvocationHandler
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Before();
		Object ret=method.invoke(userService, args); 
		After();
		return ret;
	}
	
	public void Before(){
		System.out.println("前置增强执行啦");
	}
	
	public void After(){
		System.out.println("后置增强也执行啦");
	}
	
	//第二步:调用代理过程   Proxy
	public Object getProxyInstance(){
		//通过Proxy从多个代理对象中找出一个
		return Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), this);
		//this指 InvocationHandler
		//Proxy+InvocationHandler ==>动态代理
	}

}

4.测试类TestJDK:

import org.junit.Test;

//JDK动态代理
public class TestJDk {

	@Test
	public void demo01(){
		//有个用户服务叫userService
		UserService userService =new UserServiceImpl();
		//代理家族--->所有可代理userService的对象
		MyBeanFactory ProxyFamily=new MyBeanFactory(userService);
		//用ProxyFamily.getProxyInstance()选出其中一个代理对象来代理
		UserService oneProxy=(UserService)ProxyFamily.getProxyInstance();
		oneProxy.addUser();
		oneProxy.updateUser();
		oneProxy.deleteUser();
	}
}

运行结果:
在这里插入图片描述

帮助理解动态代理

举一个通俗点的实例来说明动态代理的含义:
小明想和小红 约会+看电影

但是想要约到小红必须先经过小红家人的同意—>小红的家人就是所有的代理对象
但是也不用得到所有家长的同意,随便哪一个同意了,就可以约到小红了—>即从所有代理对象中选出一个代理对象来执行具体的操作
比如某一天小明想要约小红,小红家只有小红妈妈在家,所以小红妈妈将是小红的代理对象。

小红家长对小明这个小伙子会有一定的考察要求—>这就是增强
约会之前的考察(比如小明家庭背景如何?有房有车吗?)—>前置增强,即Before();
约会之后的考察(比如会问小红小明有没有什么不好的举动呢?)—>后置增强,即After();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值