代码拉取完成,页面将自动刷新
import aop.config.AopConfig;
import aop.service.MathCalculator;
import org.junit.jupiter.api.Test;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.SpringProxy;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.DecoratingProxy;
import org.springframework.core.SpringVersion;
import org.springframework.objenesis.Objenesis;
import org.springframework.objenesis.ObjenesisStd;
import org.springframework.objenesis.instantiator.ObjectInstantiator;
import java.lang.reflect.Proxy;
import java.util.Arrays;
/**
* AOP 原理
*
* <pre>
* 1、由开启 AOP 功能的注解入手
* 发现 @EnableAspectJAutoProxy 注解给容器中导入了 AspectJAutoProxyRegistrar
* @see EnableAspectJAutoProxy
* @see AspectJAutoProxyRegistrar
*
* 2、AspectJAutoProxyRegistrar 主要功能就是给容器中导入 AnnotationAwareAspectJAutoProxyCreator
* @see AnnotationAwareAspectJAutoProxyCreator 在 IOC 中 Bean 定义信息的名称为 internalAutoProxyCreator
* 导入过程中判断了 @EnableAspectJAutoProxy 注解上的一些属性
*
* 3、很明显重点就在 AnnotationAwareAspectJAutoProxyCreator 类上
* 3.1、先看类继承关系
* AnnotationAwareAspectJAutoProxyCreator
* * => AspectJAwareAdvisorAutoProxyCreator
* * * => AbstractAdvisorAutoProxyCreator
* * * * => AbstractAutoProxyCreator
* * * * * => ProxyProcessorSupport
* * * * * -> SmartInstantiationAwareBeanPostProcessor 关键接口,可以在 Bean 初始化完成前后做事情
* * * * * -> BeanFactoryAware 关键接口,自动装配 BeanFactory
*
* 3.2、找到接口的关键方法
* AbstractAutoProxyCreator.setBeanFactory()
* * => AbstractAdvisorAutoProxyCreator.setBeanFactory() 其中会调用 initBeanFactory()
* * => AbstractAdvisorAutoProxyCreator.initBeanFactory()
* * * => AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()
* AbstractAutoProxyCreator.有后置处理器的逻辑
*
* 3.3、DEBUG 执行流程
* * 1、创建 IOC 容器,设置主配置类 ==> new AnnotationConfigApplicationContext(AopConfig.class)
* * 2、注册配置类,初始化容器 ==> refresh()
* @see AbstractApplicationContext#refresh()
* * 3、注册 Bean 的后置处理器 ==> registerBeanPostProcessors(beanFactory)
* @see AbstractApplicationContext#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory)
* @see PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
* * * 1、获取 IOC 中已定义的后置处理器 ==> beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false)
* * * 2、获取向 IOC 中添加的其它后置处理器,例如这里的 AnnotationAwareAspectJAutoProxyCreator.class
* * * 3、区分实现了 PriorityOrdered、Ordered 接口的,和没有实现的(执行优先级:PriorityOrdered > Ordered > 没实现的)
* * * 4、主要看创建 AnnotationAwareAspectJAutoProxyCreator 实例创建
* * * * 1、创建 Bean 实例 => createBeanInstance(beanName, mbd, args)
* @see AbstractAutowireCapableBeanFactory#createBeanInstance(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
* * * * 2、Bean 属性赋值 => populateBean(beanName, mbd, instanceWrapper)
* @see AbstractAutowireCapableBeanFactory#populateBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, org.springframework.beans.BeanWrapper)
* * * * 3、初始化 Bean
* @see AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
* * * * * 1、处理 Aware 接口的方法回调 => invokeAwareMethods(beanName, bean)
* @see AbstractAutowireCapableBeanFactory#invokeAwareMethods(java.lang.String, java.lang.Object)
* * * * * * 1、执行 AbstractAdvisorAutoProxyCreator => setBeanFactory()
* * * * * * 2、执行 AnnotationAwareAspectJAutoProxyCreator => initBeanFactory()
* * * * * 2、应用后置处理器的 BeforeInitialization 方法 => applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)
* @see AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization(java.lang.Object, java.lang.String)
* * * * * 3、执行自定义的初始化方法 => invokeInitMethods(beanName, wrappedBean, mbd)
* @see AbstractAutowireCapableBeanFactory#invokeInitMethods(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
* * * * * 4、应用后置处理器的 AfterInitialization 方法 => applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)
* @see AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization(java.lang.Object, java.lang.String)
* * * * 4、AnnotationAwareAspectJAutoProxyCreator 创建成功 => AnnotationAwareAspectJAutoProxyCreator() -> BeanFactoryAspectJAdvisorsBuilder
* * * 5、向 IOC 容器中添加实例 => registerBeanPostProcessors(beanFactory, orderedPostProcessors)
* @see AbstractApplicationContext#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory)
* * * 6、完成初始化,创建剩下的单实例 Bean => finishBeanFactoryInitialization(beanFactory)
* * * * 1、获取 IOC 容器中所有的 Bean 定义信息 => beanDefinitionNames
* * * * 2、开始创建 => getBean(beanName)
* * * * * 1、创建Bean是会先在IOC中获取,不存在才创建 => Object sharedInstance = getSingleton(beanName)
* * * * * 2、获取Bean => etSingleton(beanName,回调函数)
* * * * * 3、创建Bean => createBean(beanName, mbd, args)
* * * * * 4、尝试获取代理对象 AOP,有则返回 => resolveBeforeInstantiation(beanName, mbdToUse)
* * * * * 5、创建Bean => doCreateBean(beanName, mbdToUse, args)
* * * * * 6、初始化Bean => initializeBean(beanName, exposedObject, mbd)
* </pre>
*/
public class T06_Aop {
/**
* https://blog.csdn.net/f641385712/article/details/88952482
*/
@Test
public void aopTest() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AopConfig.class);
System.out.println("SpringVersion: " + SpringVersion.getVersion());
System.out.println("================================================");
MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
// MathCalculator mathCalculator = (MathCalculator) applicationContext.getBean("mathCalculatorImpl");
mathCalculator.div(1, 1);
System.out.println("================================================");
// expected single matching bean but found 2: mathCalculatorImpl,proxyFactoryBean
// 如果通过类型获取,会找到两个 Bean:一个我们自己的实现类、一个 ProxyFactoryBean 所生产的代理类,
// 而此处我们显然是希望要生成的代理类的,因此我们只能通过名称来(或者加上 @Primary)
// MathCalculator bean = applicationContext.getBean(MathCalculator.class);
MathCalculator bean = (MathCalculator) applicationContext.getBean("proxyFactoryBean");
bean.div(1, 1);
System.out.println("================================================");
System.out.println(bean);
System.out.println(bean.getClass()); // class com.sun.proxy.$Proxy28 用的 JDK 动态代理
// 顺便说一句:这样也是没错得。因为 Spring AOP 代理出来的每个代理对象,都默认实现了这个接口(它是个标记接口)
// 它这个也就类似于所有的 JDK 代理出来的,都是 Proxy 的子类是一样的思想
SpringProxy springProxy = (SpringProxy) bean;
System.out.println("================================================");
mathCalculator.div(1, 0);
applicationContext.close();
}
@Test
public void aopJDKProxyTest() { // 接口方式
ProxyFactory proxyFactory = new ProxyFactory(new Demo());
proxyFactory.addAdvice((MethodBeforeAdvice) (method, args1, target) -> {
System.out.println("你被拦截了:方法名为:" + method.getName() + " 参数为--" + Arrays.asList(args1));
});
DemoInterface demo = (DemoInterface) proxyFactory.getProxy();
// 你被拦截了:方法名为:hello 参数为--[]
// this demo show
demo.hello();
System.out.println(proxyFactory.getTargetClass()); // class aop.AopTest$Demo
System.out.println(proxyFactory.getTargetSource()); // SingletonTargetSource for target object [aop.AopTest$Demo@fdefd3f]
System.out.println(Arrays.asList(proxyFactory.getProxiedInterfaces())); // [interface aop.AopTest$DemoInterface]
// [org.springframework.aop.support.DefaultPointcutAdvisor: pointcut [Pointcut.TRUE]; advice [aop.AopTest$$Lambda$34/0x00000008000a4c40@d83da2e]]
System.out.println(Arrays.asList(proxyFactory.getAdvisors()));
// 获取类型,看看是 JDK 代理还是 cglib 的
System.out.println(demo instanceof Proxy); // true 所有的 JDK 代理都是继承自 Proxy 的
System.out.println(demo instanceof DecoratingProxy); // true
System.out.println(demo instanceof SpringProxy); // true
System.out.println(demo.getClass()); // class aop.$Proxy7
System.out.println(Proxy.isProxyClass(demo.getClass())); // true
System.out.println(AopUtils.isCglibProxy(demo)); // false
// 测试 Advised 接口、DecoratingProxy 的内容
System.out.println(demo instanceof Advised); // true
Advised advised = (Advised) demo;
System.out.println(Arrays.asList(advised.getProxiedInterfaces())); // [interface aop.AopTest$DemoInterface]
// [org.springframework.aop.support.DefaultPointcutAdvisor: pointcut [Pointcut.TRUE]; advice [aop.AopTest$$Lambda$34/0x00000008000a4c40@d83da2e]]
System.out.println(Arrays.asList(advised.getAdvisors()));
System.out.println(advised.isExposeProxy()); // false
System.out.println(advised.isFrozen()); // false
// System.out.println(advised.removeAdvice(null));
DecoratingProxy decoratingProxy = (DecoratingProxy) demo;
System.out.println(decoratingProxy.getDecoratedClass()); // class aop.AopTest$Demo
System.out.println("-----------------------------------------------------");
// Object 的方法 ==== 所有的 Object 方法都不会被 AOP 代理,这点需要注意
System.out.println(demo.equals(new Object())); // false
System.out.println(demo.hashCode());
System.out.println(demo.getClass()); // class aop.$Proxy7
// 其余方法都没被拦截,只有 toString() 被拦截了
System.out.println(demo.toString());
// 你被拦截了:方法名为:hello 参数为--[]
// aop.AopTest$Demo@fdefd3f
}
@Test
public void aopCGLIBProxyTest() { // 子类方式
ProxyFactory proxyFactory = new ProxyFactory(new Demo());
proxyFactory.addAdvice((MethodBeforeAdvice) (method, args1, target) -> {
System.out.println("你被拦截了:方法名为:" + method.getName() + " 参数为--" + Arrays.asList(args1));
});
Demo demo = (Demo) proxyFactory.getProxy();
// 你被拦截了:方法名为:hello 参数为--[]
// this demo show
demo.hello();
System.out.println(proxyFactory.getTargetClass()); // class aop.AopTest$Demo
System.out.println(proxyFactory.getTargetSource()); // SingletonTargetSource for target object [aop.AopTest$Demo@76505305]
System.out.println(Arrays.asList(proxyFactory.getProxiedInterfaces())); // []
// [org.springframework.aop.support.DefaultPointcutAdvisor: pointcut [Pointcut.TRUE]; advice [aop.AopTest$$Lambda$34/0x00000008000a4c40@14cd1699]]
System.out.println(Arrays.asList(proxyFactory.getAdvisors()));
// 获取类型,看看是 JDK 代理还是 cglib 的
System.out.println(demo instanceof SpringProxy); // true
System.out.println(demo instanceof DecoratingProxy); // false,CGLIB 代理出来的对象没有实现接口 DecoratingProxy
System.out.println(demo.getClass()); // class aop.AopTest$Demo$$EnhancerBySpringCGLIB$$8179ec5b
System.out.println(Proxy.isProxyClass(demo.getClass())); // false
System.out.println(AopUtils.isCglibProxy(demo)); // true
// 测试 Advised 接口、DecoratingProxy 的内容
System.out.println(demo instanceof Advised); // true
Advised advised = (Advised) demo;
System.out.println(Arrays.asList(advised.getProxiedInterfaces())); // []
//[org.springframework.aop.support.DefaultPointcutAdvisor: pointcut [Pointcut.TRUE]; advice [aop.AopTest$$Lambda$34/0x00000008000a4c40@14cd1699]]
System.out.println(Arrays.asList(advised.getAdvisors()));
System.out.println(advised.isExposeProxy()); // false
System.out.println(advised.isFrozen()); // false
System.out.println("-----------------------------------------------------");
// Object 的方法 ==== 所有的 Object 方法都不会被 AOP 代理
System.out.println(demo.equals(new Object())); // false
System.out.println(demo.hashCode());
System.out.println(demo.getClass()); // class aop.AopTest$Demo$$EnhancerBySpringCGLIB$$8179ec5b
// 其余方法都没被拦截,只有 toString() 被拦截了
// 你被拦截了:方法名为:hello 参数为--[]
// aop.AopTest$Demo@76505305
System.out.println(demo.toString());
}
interface DemoInterface {
void hello();
}
// static class Demo implements DemoInterface {
static class Demo {
// @Override
public void hello() {
System.out.println("this demo show");
}
}
// ==============================================================================================================
@Test
public void objenesisStdTest() throws IllegalAccessException, InstantiationException {
Objenesis objenesis = new ObjenesisStd();
// 它竟然创建成功了
MyDemo myDemo = objenesis.newInstance(MyDemo.class);
System.out.println(myDemo); // aop.AopTest$MyDemo@2f0a87b3
System.out.println(myDemo.code); // null,特别注意:这里是 null,而不是 10
// 相当于生成了一个实例创建的工厂,接下来就可以很方便得创建实例了
// 如果你要创建多个实例,建议这么来创建
ObjectInstantiator<MyDemo> instantiator = objenesis.getInstantiatorOf(MyDemo.class);
MyDemo myDemo1 = instantiator.newInstance();
MyDemo myDemo2 = instantiator.newInstance();
System.out.println(myDemo1);
System.out.println(myDemo1.code); // null
System.out.println(myDemo2);
// 若直接这样创建,就报错 java.lang.InstantiationException: aop.AopTest$MyDemo
System.out.println(MyDemo.class.newInstance());
}
static class MyDemo {
public String code = "10";
public MyDemo(String code) {
this.code = code;
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。