aop核心的bean是什么?
一般情况会使用@EnableAspectJAutoProxy注解来使Aop注入到我们Spring的IoC容器中,那这个注入的类是啥呢
测试代码如下
@Configuration @EnableAspectJAutoProxy public class MyConfig { } public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class); String[] strings = context.getBeanDefinitionNames(); for(String s : strings){ System.out.println("name:"+s); } }
通过这个注解,把aop核心注入到ioc容器中,此时看看bean的路径是啥,
控制台输出结果如下所示
name:org.springframework.context.annotation.internalConfigurationAnnotationProcessor name:org.springframework.context.annotation.internalAutowiredAnnotationProcessor name:org.springframework.context.annotation.internalCommonAnnotationProcessor name:org.springframework.context.event.internalEventListenerProcessor name:org.springframework.context.event.internalEventListenerFactory name:myConfig name:org.springframework.aop.config.internalAutoProxyCreator
因此使用getBean去获取到这个类
AnnotationAwareAspectJAutoProxyCreator creator = (AnnotationAwareAspectJAutoProxyCreator) context.getBean("org.springframework.aop.config.internalAutoProxyCreator");
此时我们查看下AnnotationAwareAspectJAutoProxyCreator的类图继承关系
其中核心类是AbstractAutoProxyCreator、BeanPostProcessor
由于继承自BeanPostProcessor
public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
看到AbstractAutoProxyCreator抽象类实现到的的两个核心方法
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; }
@Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
因此,在AbstractAutoProxyCreator中,前置处理器是没有帮我们进行业务逻辑的处理,相关的业务逻辑处理,被其放在了后置处理器中进行处理。
由后置处理器判断,是否需要创造出一个代理对象
点进源码
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
上述代码中
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
这段作用是判断一下,你当前的这个bean是否需要做增强
然后
if (specificInterceptors != DO_NOT_PROXY)
判断下如果为空,则不是切面类表示不需要增强,put一个key,value为false,作为一个标记位。
如果非空,则执行createProxy,创建一个代理类出来。
创建代理类源码如下
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.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(getProxyClassLoader()); }
前面一些判断,到最后
return proxyFactory.getProxy(getProxyClassLoader());
这个工厂点进去,点createAopProxy()这个方法进去
public Object getProxy(@Nullable ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); }
一直点到最后,最后就来到了我们aop的最最核心代码段
@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."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }
显而易见一个判断
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); }
判断当前类,是否是接口的实现类,如果是,条件满足,则,走jdk动态代理
否则,走cglib代理模式
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)