public interface LeviService {
public int test(int i) throws Exception;
} |
@Service public class LeviServiceImpl implements LeviService {
@Override public int test(int i) throws Exception { System.out.println("执行业务逻辑。。。" + i); if(i == 5) { throw new Exception("抛出异常了..."); } return 1; } } |
@Aspect @Component public class LogAspect {
@Pointcut(value = "execution(public * com.levi.spring.aop.levi03source.LeviService.*(..))") public void pointCut() {}
/** * 在目标方法开始之前执行 */ @Before("pointCut()") public void before(JoinPoint joinpoint) { System.out.println("@Before:" + joinpoint.getSignature().getName() + " - 参数:" + Arrays.asList(joinpoint.getArgs())); }
/** * 在目标方法执行完成之后执行 */ @After("pointCut()") public void after(JoinPoint joinpoint) { System.out.println("@After:" + joinpoint.getSignature().getName() + " - 参数:" + Arrays.asList(joinpoint.getArgs())); }
/** * 目标方法执行完成之后的返回 */ @AfterReturning(value="pointCut()",returning = "result") public void afterReturning(JoinPoint joinpoint,Object result) { System.out.println("@AfterReturning:" + joinpoint.getSignature().getName() + " - 参数:" + Arrays.asList(joinpoint.getArgs()) + " - 结果:" + result); }
/** * 目标方法抛出异常之后执行 */ @AfterThrowing(value="pointCut()",throwing = "exception") public void afterThrowing(JoinPoint joinpoint,Exception exception) { System.out.println("@AfterThrowing:" + joinpoint.getSignature().getName() + " - 参数:" + Arrays.asList(joinpoint.getArgs())); }
/** * 在一个方法之前和执行后的操作 */ /*@Around("pointCut()") public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("@Around:调用执行方法之前的执行时间:" + System.currentTimeMillis());
try { proceedingJoinPoint.proceed(); //执行目标方法 } catch (Throwable e) { System.out.println("@Around:执行目标方法报错"); throw e; } System.out.println("@Around:调用执行方法之后的执行时间:" + System.currentTimeMillis()); }*/ } |
@Configuration @ComponentScan(value = "com.levi.spring.aop.levi03source") @EnableAspectJAutoProxy public class MainConfig { public static void main(String[] args) throws Exception { AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
LeviService leviService = annotationConfigApplicationContext.getBean(LeviService.class); leviService.test(2);
annotationConfigApplicationContext.close(); } } |
@EnableAspectJAutoProxy源码
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented /* * @EnableAspectJAutoProxy:注解是打开AOP功能,那么就要重点先关注下这个注解的作用,以及做了什么事情了。 * 源码: * @Import是导入类或包到IOC容器中,在这个源码中可以看到导入了AspectJAutoProxyRegistrar这个类 */ @Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
} |
AspectJAutoProxyRegistrar源码
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/* * 这个方法之前就用过,就是可以把bean注入到IOC容器中 */ @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//如果想要则注册切面注解的类到容器中 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); if (enableAspectJAutoProxy != null) { if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } }
} |
45行:AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
95行:public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry)
100行:public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,@Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
} --> 就是要注册AnnotationAwareAspectJAutoProxyCreator这个类到IOC容器中。
121行:private static BeanDefinition registerOrEscalateApcAsRequired(Class> cls, BeanDefinitionRegistry registry,@Nullable Object source)
分析:registerOrEscalateApcAsRequired方法
private static BeanDefinition registerOrEscalateApcAsRequired(Class> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//〓〓〓〓〓〓 判断IOC容器中是否已经有这个类了AnnotationAwareAspectJAutoProxyCreator if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); if (!cls.getName().equals(apcDefinition.getBeanClassName())) { int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; }
//〓〓〓〓〓〓 如果IOC容器中没有AnnotationAwareAspectJAutoProxyCreator //〓〓〓〓〓〓 则注册AnnotationAwareAspectJAutoProxyCreator到IOC容器中 //〓〓〓〓〓〓 注册的名称是org.springframework.aop.config.internalAutoProxyCreator RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; } |
小结
看到这里可能还是有点懵,但是可以看到其实就是要把AnnotationAwareAspectJAutoProxyCreator这个类要注册到IOC容器中。
AnnotationAwareAspectJAutoProxyCreator这个类的作用就是AOP切面注解代理类。
AOP的核心就是创建AnnotationAwareAspectJAutoPorxyCreator类(后置处理器),该类最终实现的接口为BeanPostProcessor类,创建好后置处理器的对象,放在容器中,其实所有注解都有对应自己的后置处理器,其实Bean组件的创建对象的时候,都会被AnnotationAwareAspectJAutoProxyCreator后置处理器拦截到创建过程。
AnnotationAwareAspectJAutoProxyCreator类的关系:
AnnotationAwareAspectJAutoProxyCreator
--> AspectJAwareAdvisorAutoProxyCreator
--> AbstractAdvisorAutoProxyCreator
--> AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
--> public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean
--> 关闭后置处理器(Bean初始化完成前后做的事情)、自动装配BeanFactory
SmartInstantiationAwareBeanPostProcessor:Bean的后置处理器:
--> InstantiationAwareBeanPostProcessor
--> BeanPostProcessor
SmartInstantiationAwareBeanPostProcessor是具有BeanPostProcessor(后置处理器)特点,也有Aware的特点,实现了BeanFactoryAware接口。
AnnotationAwareAspectJAutoProxyCreator源码分析
进入:new AnnotationConfigApplicationContext(MainConfig.class);
87行:refresh();
535行:registerBeanPostProcessors(beanFactory); 注册Bean的后置处理器来拦截Bean的创建
710行:PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { 1)、188行:先获取ioc容器已经定义了的需要创建对象的所 有BeanPostProcessor, 为什么会有已定义的呢?我们申明了@Configuration, 有可能存在了(在@EnableAspectJAutoProxy注解处理的时候, 已定义了一些组件及处理器,只是没有创建, 断点到188行可看 到有Autowired, Required,及internalAutoProxyCreator的 定义信息), 接下来要将已有的beanPostProcessor加入
//188行: //1、 //先获取IOC容器已经定义了的需要创建对象的所有BeanPostProcessor(后置处理器) //这是因为已经已经声明了@Configuration,有可能存在了在@EnableAspectJAutoProxy注解处理的时候,已经定义了一些组件和处理器,只是没有创建。 //比如:@Autowired = internalAutowiredAnnotationProcessor String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//199行 - 200行: //2、 //priorityOrderedPostProcessors:实现了PriorityOrdered接口的排序 //internalPostProcessors:Spring自身内部的 List List List List for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } }
//224行: //3、 //注册实现了PriorityOrdered接口的类到IOC容器中 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
//224行: //4、 //注册实现了Ordered接口的类到IOC容器中 //AnnotationAwareAspectJAutoProxyCreator就是通过父类继承了Ordered接口
List for (String ppName : orderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors);
//236行: //5、 //注册普通的BeanProcessor List for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors. sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); } |
小结:注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中。
创建Bean的过程:
205行:BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
进入:AbstractBeanFactory
204行:doGetBean(name, requiredType, null, false);
314行:第一次是获取不到的,那么则调用createBean方法去创建
if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } |
315行:调用的是父类DefaultSingletonBeanRegistry的方法getSingleton()方法,
sharedInstance = getSingleton(beanName, () -> {
--> 228行:获取bean,第一次都是获取不到的,所以这也是为什么上面会有return createBean(beanName, mbd, args);
singletonObject = singletonFactory.getObject();
--> 254行:addSingleton(beanName, singletonObject);,会发现会将初始化创建好的bean放到singletonObjects的Map中,完成bean初始化及创建,其实IOC容器就是这些Map,里面保存了很多单实例Bean。
AnnotationAwareAspectJAutoProxyCreator源码创建过程
接着上面:
226行:debug中可以发现,getBean获取的那个key是org.springframework.aop.config.internalAutoProxyCreator,对应的类就是AnnotationAwareAspectJAutoProxyCreator
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
进入AbstractBeanFactory - getBean():
317行:return createBean(beanName, mbd, args);,会发现获取不到还是去创建这个Bean
进入AbstractAutowireCapableBeanFactory - createBean():
501行:Object beanInstance = doCreateBean(beanName, mbdToUse, args);
532行:protected Object doCreateBean()
541行:可以看得出来这里就根据org.springframework.aop.config.internalAutoProxyCreator去创建AnnotationAwareAspectJAutoProxyCreator
instanceWrapper = createBeanInstance(beanName, mbd, args);
578行:populateBean(beanName, mbd, instanceWrapper);,创建属性
579行:exposedObject = initializeBean(beanName, exposedObject, mbd);,初始化bean
进入initializeBean();
1685行:protected Object initializeBean()
1693行:invokeAwareMethods(beanName, bean);
进入invokeAwareMethods();
1728行:((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
进入AbstractAdvisorAutoProxyCreator - setBeanFactory();
63行:initBeanFactory((ConfigurableListableBeanFactory) beanFactory);,初始化Bean
进入AnnotationAwareAspectJAutoProxyCreator - initBeanFactory();
82行:创建了ReflectiveAspectJAdvisorFactory反射类,通知对象工厂
84行:new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);,通知适配器,把aspectJAdvisorFactory通知到构建起的适配器,把aspectJAdvisorFactory重新包装一下。
===== invokeAwareMethods();,方法执行完成。AnnotationAwareAspectJAutoProxyCreator初始化完成
回到AbstractAutowireCapableBeanFactory的1698行:
1698行:wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);,执行后置处理器之前的Before,执行完会返回一个被包装的nea,也就是后置处理器的调用。
1702行:invokeInitMethods(beanName, wrappedBean, mbd);,就是声明@Bean注解时,指定初始化方法或销毁方法是什么
1710行:wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);,执行后置方法
===== BeanProcessor创建成功。
回到PostProcessorRegistrationDelegate。
248行:registerBeanPostProcessors(beanFactory, internalPostProcessors);,将创建成功的BeanPostProcessor对象加入工厂,AOP核心对象创建完成。
246行:Object sharedInstance = getSingleton(beanName);第一次获取,检查单实例在容器中是否已有
247行:if (sharedInstance != null && args == null),如果缓存中有,就直接拿
268~269行:!containsBeanDefinition(beanName)是否包含父子容器,没有则跳过
287行:markBeanAsCreated(beanName);,标记当前bean已经创建了,防止在多线程情况下,两个线程同时创建一个bean
291行:final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);,获取Bean定义信息
295行:String[] dependsOn = mbd.getDependsOn();,获取当前bean依赖的其他bean,如果有依赖的bean,就先把依赖的bean先创建出来
304~314行:如果bean是单实例
315行:haredInstance = getSingleton(beanName, () -> {,传入一个beanName创建bean
317行:return createBean(beanName, mbd, args);,若不能获取才到创建流程,Spring就是利用这个机制,保证了单实例bean的独一无二,加载一个类到IOC中,会同时加载对应的其他依赖对象,并标识已加载。
进入AbstractAutowireCapableBeanFactory - createBean();
468行:RootBeanDefinition mbdToUse = mbd;
490行:Object bean = resolveBeforeInstantiation(beanName, mbdToUse);,希望后置处理器返回一个代理对象,如果能返回代理对象就使用,如果不能创建(普通bean一般是空的返回)
进入resolveBeforeInstantiation()方法。
1035行:提前拿到mbd的bean定义信息,看是否解析过
1040行:bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
1042行:bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
进入applyBeanPostProcessorsBeforeInstantiation()方法
1064行:拿到所有后置处理器并遍历,如果后置处理器的类型是InstantiationAwareBeanPostProcessor就执行,其中AnnotationAwareAspectJAutoProxyCreator就是这种处理器,在创建Bean实例之前先尝试用后置处理器返回对象的
小结:
BeanPostProcessor是在Bean对象创建完成初始化前后调用的。
InstantiationAwareBeanPostProcessor是在创建Bean实例之前先尝试用后置处理器返回对象的,而其中AnnotationAwareAspectJAutoProxyCreator就是这种处理器,会在任何Bean创建之前尝试返回bean的实例,并且AnnotationAwareAspectJAutoProxyCreator在所有Bean创建之前会有一个拦截InstantiationAwareBeanPostProcessor,会调用 postProcessBeforeInstantiation()
AOP增强类的源码分析
接着上面:
进入AbstractAutowireCapableBeanFactory
1033行:debug对应的beanName是logAspect
1040行:applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);,进入后置处理器
1067行:ibp.postProcessBeforeInstantiation(beanClass, beanName);,进入这个方法
进入AbstractAutoProxyCreator - postProcessBeforeInstantiation()方法
248行:Object cacheKey = getCacheKey(beanClass, beanName);,先拿到logAspect的bean的名字
251行:if (this.advisedBeans.containsKey(cacheKey)),第一次处理不包含的,其实advisedBeans是已经增强的Bean,就是要判断cacheKey有没有在增强advisedBeans里面,增强advisedBeans就是保存了所有需要增强的Bean,指的是这些业务逻辑。LeviServiceImpl里面的方法是需要切面来且的,要执行它的方法不能像以前那样直接调用了,需要增强。
254行:if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName))返回fase,isInfrastructureClass()这个是判断当前bean是否是基础类型Advice、Point、Advisor、AopInfrastructureBean或者是否是切面。从跟进入就可以看到this.aspectJAdvisorFactory.isAspect(beanClass))返回是false,很明显logAspect不是切面。
254行:shouldSkip(),进入这个方法,
101行:可以看到List
103行:if (advisor instanceof AspectJPointcutAdvisor - 判断增强是否为AspectJPointcutAdvisor,很明显不是,返回false。
108行:return super.shouldSkip(beanClass, beanName);,最后返回false
创建完LogAspect对象。
回到AbstractAutoProxyCreator
302行:Object cacheKey = getCacheKey(bean.getClass(), beanName);,获取到Bean的名字,LeviServiceImpl
303行:if (!this.earlyProxyReferences.contains(cacheKey)),之前有没有代理过
304行:return wrapIfNecessary(bean, beanName, cacheKey);,如果代理过,需要的情况下进行包装下
339行:进入wrapIfNecessary方法
343行:if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))),看看增强过的bean有没有logAspect这个,返回false
346行:if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)),看是不是基础类型,是不是切面,返回false
352行:Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);,创建一个代理对象,获取当前Bean的增强器有哪些
点击进入wrapIfNecessary方法,获得增强器
343行: if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {//看增强过的bean有没有我们的bean, 返回false return bean; }
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {//看是不是基础类型,是不是切面,false this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } 重点看
352行:Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);//创建一个代理对象,获取当前bean的增强器有哪些.
进入AbstractAdvisorAutoProxyCreator - getAdvicesAndAdvisorsForBean()
76行:进入findEligibleAdvisors()
94行:List
95行:List
进入findAdvisorsThatCanApply();
1124行:ProxyCreationContext.setCurrentProxiedBeanName(beanName);,设置beanName
1126行:return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
进入AopUtils - findAdvisorsThatCanApply();
public static List if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List for (Advisor candidate : candidateAdvisors) { //遍历所有的增强器 //如果类型不是IntroductionAdvisor类型,就跳出循环 if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } boolean hasIntroductions = !eligibleAdvisors.isEmpty(); for (Advisor candidate : candidateAdvisors) { //判断是否为IntroductionAdvisor类型 if (candidate instanceof IntroductionAdvisor) { // already processed continue; } //是否能用,继续进入这个方法 if (canApply(candidate, clazz, hasIntroductions)) { //只要能用就加入eligibleAdvisors eligibleAdvisors.add(candidate); } } //返回适合LeviServiceImpl能用的增强器 return eligibleAdvisors; } |
public static boolean canApply(Advisor advisor, Class> targetClass, boolean hasIntroductions) { if (advisor instanceof IntroductionAdvisor) { return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass); //开始匹配 } else if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pca = (PointcutAdvisor) advisor; //切入点表达式算一下每个方法是否能匹配并返回 return canApply(pca.getPointcut(), targetClass, hasIntroductions); } else { // It doesn't have a pointcut so we assume it applies. return true; } } |
wrapIfNecessary方法分析小结:
进入AbstractAutoProxyCreator类:
247行:postProcessBeforeInstantiation方法。
248行:Object cacheKey = getCacheKey(beanClass, beanName);,先拿到logAspect的bean的名字
251行:if (this.advisedBeans.containsKey(cacheKey)),第一次处理不包含的,其实advisedBeans是已经增强的Bean,就是要判断cacheKey有没有在增强advisedBeans里面,增强advisedBeans就是保存了所有需要增加的Bean,指的是这些业务逻辑。LeviServiceImpl里面的方法是需要切面来且的,要执行它的方法不能像以前那样直接调用了,需要增强。
wrapIfNecessary方法分析完成后,回到AbstractAutoProxyCreator:
353行:
//创建一个代理对象,获取当前bean的增强器有哪些 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); //bean的增强器获取完成,如果这个bean有增强器就不为空 if (specificInterceptors != DO_NOT_PROXY) { //把当前以及增强过的bean保存到当前bean在advisedBeans中 this.advisedBeans.put(cacheKey, Boolean.TRUE); //如果当前bean有了增强器,那么则创建代理对象增强此bean(如果此bean需要增强,则创建此bean的代理对象) //▲ 进入createProxy() Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } |
protected Object createProxy(Class> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); }
ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } }
//先拿到增强器 Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); //把增强器的通知方法保存到ProxyFactory中 proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } //用proxyFactory.getProxy代理工厂创建代理对象 //▲ 进入getProxy()方法 return proxyFactory.getProxy(getProxyClassLoader()); } |
进入ProxyFactory类:
110行:return createAopProxy().getProxy(classLoader);
进入createAopProxy()方法,即进到ProxyFactory父类 > ProxyCreatorSupport:
105行:return getAopProxyFactory().createAopProxy(this);
进入DefaultAopProxyFactory > createAopProxy();方法:
@Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } //如果是接口就使用JDK的动态代理 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } //如果不是接口就用CGlib创建动态代理 return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } } |
把LeviServiceImpl给注释,改为单个类,不在实现接口。
@Service //public class LeviServiceImpl implements LeviService { public class LeviServiceImpl {
// @Override public int test(int i) throws Exception { System.out.println("执行业务逻辑。。。" + i); if(i == 5) { throw new Exception("抛出异常了..."); } return 1; } } |
@Component public class LogAspect {
// @Pointcut(value = "execution(public * com.levi.spring.aop.levi03source.LeviService.*(..))") @Pointcut(value = "execution(public * com.levi.spring.aop.levi03source.LeviServiceImpl.*(..))") public void pointCut() {} …… } |
DefaultAopProxyFactory > createAopProxy();方法。
51行:if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)),debug查看结果
60行:最后进入return new ObjenesisCglibAopProxy(config);,证明CGLib是用于非接口的,JDK动态代理是用于接口的
跟进这个类new ObjenesisCglibAopProxy(config);
51行:super(config);进入父类CglibAopProxy
父类CglibAopProxy:
131行:this.advised = config;,可以看到会将这个配置给到这个代理类,进入AdvisedDispatcher这个代理类,会发现AdvisedDispatcher是一个内部类,属于CglibAopProxy。
小结:整个代理对象建立完成,现在已经知道AOP的切面对象是由一个代理对象在代理着。
public class MainConfig { public static void main(String[] args) throws Exception { AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
//JDK动态代理或CGLib增强了代理对象leviService LeviService leviService = annotationConfigApplicationContext.getBean(LeviService.class); //以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,带对象就会执行通知方法的流程 leviService.test(2);//执行这个test方法时CGLib就会调用那些保存起来的通知方法
annotationConfigApplicationContext.close(); } } |
切面拦截的执行
接着上面:
进入CglibAopProxy:
661行:Object oldProxy = null;,打上debug标记,另外MainConfig > leviService.test(2);,打上debug
673行:Class> targetClass = (target != null ? target.getClass() : null);,可以看到就是LeviServiceImpl
674行:List
public List@Nullable Class> targetClass) { //缓存起来方便下次使用 MethodCacheKey cacheKey = new MethodCacheKey(method); Listthis.methodCache.get(cacheKey); if (cached == null) { //从advisorChainFactory拦截器链工厂中获取test()方法的拦截器链 //▲ 进入getInterceptorsAndDynamicInterceptionAdvice();这个方法 cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( this, method, targetClass); this.methodCache.put(cacheKey, cached); } //如果获取了就返回 return cached; } |
51行:DefaultAdvisorChainFactory > getInterceptorsAndDynamicInterceptionAdvice public List Advised config, Method method, @Nullable Class> targetClass) {
//config就是proxyFactory,其中config.getAdvisors()保存了5个拦截器,包括一个默认的ExposeInvocationInterceptor ListinterceptorList = new ArrayList<>(config.getAdvisors().length); Class> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass()); boolean hasIntroductions = hasMatchingIntroductions(config, actualClass); AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
//遍历所有增强器,将其转换为Interceptor for (Advisor advisor : config.getAdvisors()) {
//判断是否是PointcutAdvisor类型 if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
//▲ 进入getInterceptors()方法 MethodInterceptor[] interceptors = registry.getInterceptors(advisor); MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) { if (mm.isRuntime()) { for (MethodInterceptor interceptor : interceptors) { interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm)); } } else {
//将增强器转换为List interceptorList.addAll(Arrays.asList(interceptors)); } } } } else if (advisor instanceof IntroductionAdvisor) { IntroductionAdvisor ia = (IntroductionAdvisor) advisor; if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
//将增强器转换为List Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } else { Interceptor[] interceptors = registry.getInterceptors(advisor);
将增强器转换为List interceptorList.addAll(Arrays.asList(interceptors)); } }
return interceptorList; } |
79行:DefaultAdvisorChainFactory public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { List Advice advice = advisor.getAdvice();
//如果是MethodInterceptor类型,就直接加入interceptors集合 if (advice instanceof MethodInterceptor) { interceptors.add((MethodInterceptor) advice); }
//有些advice不是实现MethodInterceptor接口,需要使用adapter进行包装转换 //实际上就是加一个AfterReturningAdvice后置通知 for (AdvisorAdapter adapter : this.adapters) { //如果不是,需要AdvisorAdapter,适配器帮它转过来,将增强器转为interceptors if (adapter.supportsAdvice(advice)) { interceptors.add(adapter.getInterceptor(advisor)); } } if (interceptors.isEmpty()) { throw new UnknownAdviceTypeException(advisor.getAdvice()); }
//把每个adivce转换为MethodInterceptor数组并返回,得到拦截器链(每个方法被包装为方法拦截器,以后的方法的执行都是利用MethodInterceptor机制执行) return interceptors.toArray(new MethodInterceptor[0]); } |
在getInterceptorsAndDynamicInterceptionAdvice();方法 > 执行完成 > 拦截器链就建立起来了 > 回到CglibAopProxy:
678行:if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())),判断拦截链是否为空
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { //如果拦截链为空,则直接直接目标方法 Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = methodProxy.invoke(target, argsToUse); } |
688行:retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();使用proceed();来执行拦截器链,是触发调用拦截器的过程。整个执行过程就是用来触发调用拦截器链的过程。其中把需要执行的目标对象,目标方法、拦截器链等信息传入创建 CglibMethodInvocation对象,并传入一些执行参。
进入ReflectiveMethodInvocation > proceed();方法
162行:this.currentInterceptorIndex,是用来记录当前拦截器的索引,默认为-1
//LeviServiceImpl的currentInterceptorIndex=5 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { //如果没有拦截器执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法 //如果代码执行到了这里,就表示前置通知已经处理完了,并执行完@Before注解的打印内容,并准备调用目标方法 return invokeJoinpoint(); }
//每次+1,取一个拦截器 Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); |
185行:return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);,调用此方法,进入invoke();看
进入 ExposeInvocationInterceptor > invoke();
public Object invoke(MethodInvocation mi) throws Throwable { //什么是invocation,跟进去 MethodInvocation oldInvocation = invocation.get();
//第一次mi还没共享,所以先设置进入 invocation.set(mi); try { //重新进行CglibProxy.proceed(),执行第二个拦截器 return mi.proceed(); } finally { invocation.set(oldInvocation); } } |
60行:ThreadLocal同一线程共享数据,要把MethodInvocation要共享,然后MethodInvocation就是上面的mi=CglibAopProxy
private static final ThreadLocal new NamedThreadLocal<>("Current AOP method invocation"); |
1、定义切面的注解:@Before、@After、@AfterReturning、@AfterThrowing、@Around
2、启动切面的注解:@EnableAspectJAutoProxy > 实际处理类(AspectJAutoProxyRegistrar) > 注册到IOC容器的名称(org.springframework.aop.config.internalAutoProxyCreator) > 执行后置处理器 > 在创建所有bean之前会有一个拦截器InstantiationAwareBeanPostProcessor
3、切面增强类:先拿到切面的bean(先缓存) > 是否代理过这个类 > 包装这个类进行代理并获取到当前的增强器列表 > 接口就用JDK动态代理 > 非接口就用CGLib动态代理 > 增强器列表构建拦截链
为什么Java动态代理必须是接口?
Java是单继承多实现的,Java底层的class字节码是一个$Proxy是继承了Proxy类,所以只能是接口。
Java动态代理与CGLib代理的原理?
JDK1.3后,Java提供了动态代理技术,允许在运行期间创建接口的代理实例。主要涉及java.lang.reflect包下的2个类:Proxy和InvocationHandler。
InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑(如前后打印日志),并通过反射机制调用目标类的代码,动态的将横切逻辑和业务编织在一起。
Java动态代理有个限制就是只能为接口创建代理实例,而对于没有通过接口定义业务方法的类,只能通过CGLib来创建动态代理类了。
CGLib(Code Generation Library)是一个基于ASM的字节码生成库,允许在运行时对字节码进行修改和动态生成。
CGLib通过继承方式实现代理,在子类中采用方法拦截的技术拦截所有父类方法的调用并顺势织入横切逻辑。
Java动态代理技术原理:
通过实现InvocationHandler接口创建自己的调用处理器。
通过为代理类(Proxy)指定ClassLoader对象和一组interface来创建动态代理。
通过反射机制获取动态代理类的构造函数,其唯一参数类型就是调用处理器接口类型。
通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数传入。
Java动态代理是面向接口的代理模式,如果被代理目标没有接口,那么Spring也无能为力,Spring通过Java反射机制生成被代理接口的新的匿名实现类,重写了其中AOP的增强方法。
CGLib动态代理原理:
利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
Java和CGLib动态代理区别:
JDK动态代理:面向接口。
CGLib动态代理是通过字节码底层继承要代理类来实现,因此如果被代理类是被final关键字修饰就会失败。
public final class LeviServiceImpl |
AopConfigException: Could not generate CGLIB subclass of class com.levi.spring.aop.levi03source.LeviServiceImpl |
Java和CGLib动态代理性能对比:
网上有很多测试,在JDK1.6和1.7的时候,JDK动态代理的速度要比CGLib动态代理要满,但是没有10倍那么大的差距。但是在JDK1.8之后,JDK动态代理速度已经是和CGLib动态代理的速度差不多了。
Spring怎么使用JDK动态代理和CGLib?
1、Spring默认使用JDK动态代理实现机制。
2、如果要被代理的对象是个接口实现类,那么Spring会使用JDK动态代理来完成。
3、如果被代理的对象不是个实现类,那么Spring会强制使用CGLib来实现动态代理。