AOP底层实现原理
一、JDK
- 核心思想:
原始类和代理类实现相同的接口
使用JDK自带api创建动态代理
public class JDKTest{
public static void main(String[] args){
// 获取原始对象
UserService userService = new UserServiceImpl();
ClassLoader classLoader = JDKTest.class.getClassLoader();
Class<?>[] interfaces = userService.getClass().getInterfaces();
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("====执行原始方法之前====");
// 运行原始方法
Object ret = method.invoke(userService, args);
System.out.println("====执行原始方法之后====");
return ret;
}
};
UserService userServiceProxy = (UserService)Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
userServiceProxy.register(new User());
userServiceProxy.login("zhl", "123");
}
}
- 类加载器的作用(ClassLoader)
类加载器把对应类的字节码文件(.class)加载到JVM,创建这个类的Class对象,进而创建这个类的对象。
动态字节码技术没有创建代理类的源文件和字节码文件,但是需要创建动态代理类的对象,所以需要借用一个类加载器。 - interfaces
原始类实现的接口 - InvocationHandler
为原始类中的原始方法添加额外功能
二、Cglib
- 核心思想:
代理类继承原始类
使用Cglib创建动态代理,创建过程大致和JDK方式类似
public class CglibTest {
public static void main(String[] args) {
// 原始对象
UserService userService = new UserService();
Enhancer enhancer = new Enhancer();
// 为动态代理类设置类加载器
enhancer.setClassLoader(CglibTest.class.getClassLoader());
// 设置原始类为父类,添加额外功能
enhancer.setSuperclass(userService.getClass());
MethodInterceptor interceptor = new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("----------cglib before--------");
Object ret = method.invoke(userService, args);
System.out.println("----------cglib after--------");
return ret;
}
};
// callback <===> invocationHandler
enhancer.setCallback(interceptor);
// 创建代理对象
UserService serviceProxy = (UserService) enhancer.create();
serviceProxy.login("zzz", "222");
serviceProxy.register(new User());
}
}
三、BeanPostProcessor
Spring工厂如何加工原始对象?
思路分析:
简单代码实现:
public class ProxyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
InvocationHandler invocation = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("--------核心功能之前---------");
Object ret = method.invoke(bean, args);
System.out.println("--------核心功能之后---------");
return ret;
}
};
return Proxy.newProxyInstance(ProxyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(),invocation);
}
}
<bean id="userService" class="com.zhl.factory.UserServiceImpl"/>
<!--对当前配置文件中的所有bean进行加工-->
<bean id="proxyBeanPostProcessor" class="com.zhl.factory.ProxyBeanPostProcessor"/>
这里的实现比较粗糙,没有引入切入点,对整个Spring工厂中的bean都进行了加工。