标签:ota nbsp raw source error bst 注册 on() sim
新的一年 只争朝夕 不负韶华 加油加油??
(一)自定义便签使用
步骤:(前提要将Spring Core包加入项目中)
(1)创建需要扩展的组件
(2)定义一个XSD文件描述组件内容
(3)创建一个文件,实现BeanDefinitionParse接口,用来解析XSD文件中的定义和组件定义
(4)创建一个Handler文件,扩展自NamespaceHandleSupport,目的是将组件注册到Spring容器
(5)编写Spring.Handlers和Spring.schemas文件
具体代码如下:
1 public class User { 2 private String id; 3 private String usrnm; 4 private String email; 5 6 public String getUsrnm() { 7 return usrnm; 8 } 9 10 public String getId() { 11 return id; 12 } 13 14 public User setId(String id) { 15 this.id = id; 16 return this; 17 } 18 19 public User setUsrnm(String usrnm) { 20 this.usrnm = usrnm; 21 return this; 22 } 23 24 public String getEmail() { 25 return email; 26 } 27 28 public User setEmail(String email) { 29 this.email = email; 30 return this; 31 } 32 }
1 public class UserBeanDefinitionParse extends AbstractSimpleBeanDefinitionParser { 2 3 // 会用到的 4 @Override 5 protected Class getBeanClass(Element ele){ 6 return User.class; 7 } 8 9 @Override 10 protected void doParse(Element element, BeanDefinitionBuilder builder) { 11 String name = element.getAttribute("usrnm"); 12 String email = element.getAttribute("email"); 13 if (StringUtils.hasText(name)) { 14 builder.addPropertyValue("usrnm", name); 15 } 16 if (StringUtils.hasText(email)) { 17 builder.addPropertyValue("email", email); 18 } 19 } 20 }
1 http\://www.vi.com/schema/user.xsd=aotutag.xsd
1 public class AppTest { 2 3 @Test 4 public void test() { 5 String path = "spring-config.xml"; 6 BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource(path)); 7 ApplicationContext bf = new ClassPathXmlApplicationContext(path); 8 User bean = bf.getBean(User.class); 9 System.out.println(" name: " + bean.getUsrnm() + " email: " + bean.getEmail()); 10 } 11 12 13 }
运行结果:
name: miya email: miya@163.com
(二)自定义标签解析
1 /** 2 * Parse a custom element (outside of the default namespace). 3 * @param ele the element to parse 4 * @param containingBd the containing bean definition (if any) 5 * @return the resulting bean definition 6 */ 7 @Nullable 8 public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) { 9 // 获取对应的命名空间 10 String namespaceUri = getNamespaceURI(ele); 11 if (namespaceUri == null) { 12 return null; 13 } 14 NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); 15 if (handler == null) { 16 error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele); 17 return null; 18 } 19 return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); 20 }
(1)获取命名空间
(2)根据命名空间找到对应的处理器
(3)解析
(一)获取自定义标签处理器
1 /** 2 * Locate the {@link NamespaceHandler} for the supplied namespace URI 3 * from the configured mappings. 4 * @param namespaceUri the relevant namespace URI 5 * @return the located {@link NamespaceHandler}, or {@code null} if none found 6 */ 7 @Override 8 @Nullable 9 public NamespaceHandler resolve(String namespaceUri) { 10 //获取已配置的handlers 11 Map<String, Object> handlerMappings = getHandlerMappings(); 12 //根据命名空间找到对应的处理类 13 Object handlerOrClassName = handlerMappings.get(namespaceUri); 14 if (handlerOrClassName == null) { 15 return null; 16 } 17 else if (handlerOrClassName instanceof NamespaceHandler) { 18 // 已经做过解析 直接从缓存中读取 19 return (NamespaceHandler) handlerOrClassName; 20 } 21 else { 22 String className = (String) handlerOrClassName; 23 try { 24 // 使用反射将类路径转化为类 25 Class<?> handlerClass = ClassUtils.forName(className, this.classLoader); 26 if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) { 27 throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri + 28 "] does not implement the [" + NamespaceHandler.class.getName() + "] interface"); 29 } 30 //初始化类 31 NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass); 32 // 调用自定义的NamespaceHandler的init(方法) 33 namespaceHandler.init(); 34 // 记录在缓存中 35 handlerMappings.put(namespaceUri, namespaceHandler); 36 return namespaceHandler; 37 } 38 catch (ClassNotFoundException ex) { 39 throw new FatalBeanException("Could not find NamespaceHandler class [" + className + 40 "] for namespace [" + namespaceUri + "]", ex); 41 } 42 catch (LinkageError err) { 43 throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" + 44 className + "] for namespace [" + namespaceUri + "]", err); 45 } 46 } 47 }
(1)获取所有的handlers
(2)根据命名空间获取相应的handler
(3)已做解析直接获取
(4)没有做过解析,则使用反射获取类,调用自定义的handle,并记录在缓存中
(二)标签解析
1 /** 2 * Parses the supplied {@link Element} by delegating to the {@link BeanDefinitionParser} that is 3 * registered for that {@link Element}. 4 */ 5 @Override 6 @Nullable 7 public BeanDefinition parse(Element element, ParserContext parserContext) { 8 // 根据localname获取相应的解析器(在自定义的方法中注册的) 9 BeanDefinitionParser parser = findParserForElement(element, parserContext); 10 return (parser != null ? parser.parse(element, parserContext) : null); 11 }
(1)获取解析器
(2)解析
1 @Override 2 @Nullable 3 public final BeanDefinition parse(Element element, ParserContext parserContext) { 4 AbstractBeanDefinition definition = parseInternal(element, parserContext); 5 if (definition != null && !parserContext.isNested()) { 6 try { 7 String id = resolveId(element, definition, parserContext); 8 // 必须有id 9 if (!StringUtils.hasText(id)) { 10 parserContext.getReaderContext().error( 11 "Id is required for element ‘" + parserContext.getDelegate().getLocalName(element) 12 + "‘ when used as a top-level tag", element); 13 } 14 String[] aliases = null; 15 if (shouldParseNameAsAliases()) { 16 String name = element.getAttribute(NAME_ATTRIBUTE); 17 if (StringUtils.hasLength(name)) { 18 aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name)); 19 } 20 } 21 BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases); 22 registerBeanDefinition(holder, parserContext.getRegistry()); 23 if (shouldFireEvents()) { 24 BeanComponentDefinition componentDefinition = new BeanComponentDefinition(holder); 25 postProcessComponentDefinition(componentDefinition); 26 parserContext.registerComponent(componentDefinition); 27 } 28 } 29 catch (BeanDefinitionStoreException ex) { 30 String msg = ex.getMessage(); 31 parserContext.getReaderContext().error((msg != null ? msg : ex.toString()), element); 32 return null; 33 } 34 } 35 return definition; 36 }
真正的解析
(1)调用自定义的解析函数,parseInternal方法
(2)将解析后的AbstractBeanDefinition封装成BeanDefinitionHolder,完成注册
1 @Override 2 protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { 3 BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(); 4 5 String parentName = getParentName(element); 6 if (parentName != null) { 7 builder.getRawBeanDefinition().setParentName(parentName); 8 } 9 // 会调用自定会议解析器中的getBeanClass方法 10 Class<?> beanClass = getBeanClass(element); 11 if (beanClass != null) { 12 builder.getRawBeanDefinition().setBeanClass(beanClass); 13 } 14 else { 15 String beanClassName = getBeanClassName(element); 16 if (beanClassName != null) { 17 builder.getRawBeanDefinition().setBeanClassName(beanClassName); 18 } 19 } 20 builder.getRawBeanDefinition().setSource(parserContext.extractSource(element)); 21 BeanDefinition containingBd = parserContext.getContainingBeanDefinition(); 22 if (containingBd != null) { 23 // Inner bean definition must receive same scope as containing bean. 24 builder.setScope(containingBd.getScope()); 25 } 26 if (parserContext.isDefaultLazyInit()) { 27 // Default-lazy-init applies to custom bean definitions as well. 28 builder.setLazyInit(true); 29 } 30 //调用子类的doParse方法 31 doParse(element, parserContext, builder); 32 return builder.getBeanDefinition(); 33 }
标签:ota nbsp raw source error bst 注册 on() sim
原文地址:https://www.cnblogs.com/VVII/p/12154249.html