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,由它接管实际的工作。
为什么要使用动态代理
简言之,为了避免代码混乱和代码分散。
动态代理过程——直接代码讲解代理过程
- 接口:UserService
- 接口实现类:UserServiceImpl
- 代理类:MyBeanFactory
- 测试类: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();