spring aop 源码分析
来源:互联网 发布:信息软件开发 编辑:程序博客网 时间:2024/06/11 01:46
spring在解析xml配置文件的时候,会根据传入的namespaceUri找到对应的NamespaceHandler,这个映射是在spring.handlers中配置的。
拿aop举例:
spring aop的配置文件肯定是要加这么一段aop的命名空间xmlns:aop=”http://www.springframework.org/schema/aop”
我们在spring-aop的META-INF/spring.handlers文件中找到了对应的namespaceHandler
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
下面就是看AopNamespaceHandler如何处理aop标签了。
public class AopNamespaceHandler extends NamespaceHandlerSupport { /** * Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the * '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}' * and '{@code scoped-proxy}' tags. */ @Override public void init() { // In 2.0 XSD as well as in 2.1 XSD. registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser()); registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser()); registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator()); // Only in 2.0 XSD: moved to context namespace as of 2.1 registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser()); }}
看一下AspectJAutoProxyBeanDefinitionParser的内部实现
@Override public BeanDefinition parse(Element element, ParserContext parserContext) { AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element); extendBeanDefinition(element, parserContext); return null; }
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary( ParserContext parserContext, Element sourceElement) {//注册或升级AutoProxyCreator定义beanName为org.springframework.aop.config.internalAutoProxyCreator的BeanDefinition BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); //对于proxy-target-class以及expose-proxy属性的处理 useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); //注册组件并通知,便于监听器进一步处理 //其中beanDefinition的className为AnnotationAwareAspectJAutoProxyCreator registerComponentIfNecessary(beanDefinition, parserContext); }
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) { return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); }
通过自定义配置完成对AnnotationAwareAspectJAutoProxyCreator类型的自动注册。
AnnotationAwareAspectJAutoProxyCreator 实现了BeanPostProcessor接口,当spring加载这个bean的时候会在实例化前调用postProcessAfterInitialization方法。aop的大门就此打开了
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (beanName != null && 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; } //如果存在增强方法则创建代理 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; }
获取增强方法的实现:
@Override protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) { List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); }
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { List<Advisor> candidateAdvisors = findCandidateAdvisors();//获取所有的增强 List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); //从所有增强中寻找适合该bean的增强并且应用 extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
@Override protected List<Advisor> findCandidateAdvisors() { // Add all the Spring advisors found according to superclass rules. List<Advisor> advisors = super.findCandidateAdvisors(); // Build Advisors for all AspectJ aspects in the bean factory. advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); return advisors; }
public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = null; synchronized (this) { aspectNames = this.aspectBeanNames; if (aspectNames == null) { List<Advisor> advisors = new LinkedList<>(); aspectNames = new LinkedList<>(); //获取所有的beanName String[] beanNames=BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false); //循环所有beanName找出对应的增强方法 for (String beanName : beanNames) { if (!isEligibleBean(beanName)) { continue; } // We must be careful not to instantiate beans eagerly as in this // case they would be cached by the Spring container but would not // have been weaved Class<?> beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; } //如果存在Aspect注解 if (this.advisorFactory.isAspect(beanType)) { aspectNames.add(beanName); AspectMetadata amd = new AspectMetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); //解析标记AspectJ注解额增强方法 List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); if (this.beanFactory.isSingleton(beanName)) { this.advisorsCache.put(beanName, classAdvisors); } else { this.aspectFactoryCache.put(beanName, factory); } advisors.addAll(classAdvisors); } else { // Per target or per this. if (this.beanFactory.isSingleton(beanName)) { throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); this.aspectFactoryCache.put(beanName, factory); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } this.aspectBeanNames = aspectNames; return advisors; } } if (aspectNames.isEmpty()) { return Collections.emptyList(); } List<Advisor> advisors = new LinkedList<>(); for (String aspectName : aspectNames) { List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName); if (cachedAdvisors != null) { advisors.addAll(cachedAdvisors); } else { MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } return advisors; }
下一篇了解getAdvisors方法是如何实现增强器的获取的
阅读全文
0 0
- spring aop源码分析
- Spring Aop源码分析
- spring aop 源码分析
- Spring源码分析:实现AOP- -
- Spring实现AOP源码分析
- spring源码分析之aop
- Spring源码分析-深入浅出AOP(图文分析)
- 理解Spring AOP 原理(三)Spring AOP 源码分析
- Spring AOP介绍及源码分析
- Spring AOP介绍及源码分析
- Spring AOP介绍及源码分析
- Spring AOP介绍及源码分析
- Spring AOP介绍及源码分析
- Spring AOP介绍及源码分析
- Spring AOP声明式应用源码分析
- Spring AOP介绍及源码分析
- Spring源码学习-5.AOP原理分析
- Spring AOP介绍及源码分析
- TCP/IP学习随笔
- hdu-4638-Group-(树状数组,离线操作)
- Jzoj4605 排序
- leetcode 169. Majority Element
- 用cookie实现记住密码
- spring aop 源码分析
- U-BLOX GPS 模块及GPRMC指令解析
- 将链表倒置(改变指针方向)
- 重装jdk后又重装的Tomcat,jdk配置环境变量没有问题,Tomcat.exe一直是闪退
- Linux系统中关于用户的相关操作
- static 的作用
- html5录音+百度语音实现语音识别
- 经纬度10进制快速转换
- RTKLIB:RTK使用介绍