国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Spring自定義配置Schema可擴(kuò)展(二)

2019-11-26 14:38:53
字體:
供稿:網(wǎng)友

命名空間支持

要實(shí)現(xiàn)命名空間支持,需要繼承自NamespaceHandlerSupport。

package com.codestd.spring.cxf.config.schema;import org.springframework.beans.factory.xml.NamespaceHandlerSupport;import com.codestd.spring.cxf.config.EndpointBeanProcessor;/*** 處理命名空間* @author jaune(Wang Chengwei)* @since 1.0.0*/public class WebServiceAnnotationNamespaceHandler extends NamespaceHandlerSupport {@Overridepublic void init() {// TODO Auto-generated method stubthis.registerBeanDefinitionParser("annotation-endpoint", new AnnotationBeanDefinitionParser(EndpointBeanProcessor.class));}}

通過registerBeanDefinitionParser方法講配置支持添加到Spring中。annotation-endpoint是配置支持的元素。AnnotationBeanDefinitionParser是處理配置的類。EndpointBeanProcessor是處理@Endpoint注解的Bean的類,后面會(huì)有詳細(xì)的講述。

處理配置

需要實(shí)現(xiàn)BeanDefinitionParser

package com.codestd.spring.cxf.config.schema;import org.springframework.beans.factory.config.BeanDefinition;import org.springframework.beans.factory.support.RootBeanDefinition;import org.springframework.beans.factory.xml.BeanDefinitionParser;import org.springframework.beans.factory.xml.ParserContext;import org.springframework.util.StringUtils;import org.w3c.dom.Element;/*** @author jaune(Wang Chengwei)* @since 1.0.0*/public class AnnotationBeanDefinitionParser implements BeanDefinitionParser {private final Class<?> beanClass;public AnnotationBeanDefinitionParser(Class<?> beanClass) {this.beanClass = beanClass;}@Overridepublic BeanDefinition parse(Element element, ParserContext parserContext) {RootBeanDefinition beanDefinition = new RootBeanDefinition();beanDefinition.setBeanClass(beanClass);beanDefinition.setLazyInit(false);String id = element.getAttribute("id");if(id == null || id.length() == 0 ){String name = element.getAttribute("name");if(!StringUtils.isEmpty(name)) id = name;else id = beanClass.getName();}if (parserContext.getRegistry().containsBeanDefinition(id)) {throw new IllegalStateException("Duplicate spring bean id " + id);}parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);String annotationPackage = element.getAttribute("package");if(!StringUtils.isEmpty(annotationPackage))beanDefinition.getPropertyValues().add("annotationPackage", annotationPackage);return beanDefinition;}}

BeanDefinitionParser的應(yīng)用參見Spring官方文檔。

Bean注冊(cè)工具類

package com.codestd.spring.cxf.config;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.BeanDefinition;import org.springframework.beans.factory.support.BeanDefinitionBuilder;import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.context.ConfigurableApplicationContext;/*** Registry Bean. Must inject the spring ApplicationContext.* @author jaune(Wang Chengwei)* @since 1.0.0*/public class BeanRegistry implements ApplicationContextAware{private ApplicationContext applicationContext;private ConfigurableApplicationContext configurableApplicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;if(applicationContext instanceof ConfigurableApplicationContext){this.configurableApplicationContext = (ConfigurableApplicationContext)this.applicationContext;}}public BeanRegistry(){}public BeanRegistry(ApplicationContext applicationContext){this.setApplicationContext(applicationContext);}public BeanDefinition register(Class<?> clazz){if(configurableApplicationContext == null)return null;BeanDefinitionRegistry beanDefinitonRegistry = (BeanDefinitionRegistry)configurableApplicationContext.getBeanFactory();BeanDefinitionBuilder beanDefinitionBuilder = this.createBuilder(clazz);BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();beanDefinitonRegistry.registerBeanDefinition(clazz.getName(),beanDefinition);return beanDefinition;}private BeanDefinitionBuilder createBuilder(Class<?> clazz){BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);return beanDefinitionBuilder;}}

處理@Endpoint

package com.codestd.spring.cxf.config;import org.springframework.beans.BeansException;import org.springframework.beans.factory.DisposableBean;import org.springframework.beans.factory.config.BeanFactoryPostProcessor;import org.springframework.beans.factory.config.BeanPostProcessor;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;import org.springframework.core.type.filter.AnnotationTypeFilter;import org.springframework.util.StringUtils;import com.codestd.spring.cxf.annotation.Endpoint;/*** @author jaune(WangChengwei)* @since 1.0.0*/public class EndpointBeanProcessor implements BeanFactoryPostProcessor, DisposableBean, BeanPostProcessor, ApplicationContextAware{private final String COMMA_SPLIT_PATTERN = ",";private ApplicationContext applicationContext;private String annotationPackage;private String[] annotationPackages;private BeanRegistry beanRegistry;public void setAnnotationPackage(String annotationPackage) {this.annotationPackage = annotationPackage;if(!StringUtils.isEmpty(this.annotationPackage))this.annotationPackages = this.annotationPackage.split(this.COMMA_SPLIT_PATTERN);}@Overridepublic void setApplicationContext(ApplicationContext applicationContext)throws BeansException {this.applicationContext = applicationContext;this.beanRegistry = new BeanRegistry(this.applicationContext);}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName)throws BeansException {if(!this.isMatchPackage(bean))return bean;Endpoint endpoint = bean.getClass().getAnnotation(Endpoint.class);if(endpoint != null){System.out.println(bean.getClass());}return bean;}@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName)throws BeansException {return bean;}@Overridepublic void destroy() throws Exception {}/*** 包是否匹配* @param bean* @return*/private boolean isMatchPackage(Object bean){if (annotationPackages == null || annotationPackages.length == 0) {return true;}String beanClassName = bean.getClass().getName();for (String pkg : annotationPackages) {if (beanClassName.startsWith(pkg)) {return true;}}return false;}/*** 掃描{@link com.codestd.spring.cxf.annotation.Endpoint}注解*/@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {if (annotationPackage == null || annotationPackage.length() == 0) {return;}if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry)beanFactory;ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry,true);AnnotationTypeFilter filter = new AnnotationTypeFilter(Endpoint.class);scanner.addIncludeFilter(filter);scanner.scan(annotationPackages);}}}

這里已經(jīng)實(shí)現(xiàn)了注解的掃描。然后需要在postProcessAfterInitialization方法中寫業(yè)務(wù)處理代碼。AfterInitialization表示Bean已經(jīng)創(chuàng)建并且注入屬性。

postProcessBeforeInitialization主要是為了在Bean實(shí)例化時(shí)注入屬性。

讓Spring識(shí)別擴(kuò)展

首先在classpath的META-INF下創(chuàng)建spring.handlers,內(nèi)容如下

http/://www.codestd.com/schema/std/ws=com.codestd.spring.cxf.config.schema.WebServiceAnnotationNamespaceHandler

在這個(gè)文件中指明了哪個(gè)命名空間需要哪個(gè)類來處理。
然后再創(chuàng)建spring.schemas

http/://www.codestd.com/schema/std/ws/stdws-1.0.xsd=META-INF/schema/stdws-1.0.xsd

指明了Sechma文件的位置,Spring會(huì)使用這里制定的xsd文件來驗(yàn)證配置是否正確。

測(cè)試

創(chuàng)建接口

package com.codestd.spring.cxf.ws;import javax.jws.WebService;/*** @author jaune(Wang Chengwei)* @since 1.0.0*/@WebServicepublic interface HelloService {public String syHi(String name);}

實(shí)現(xiàn)類

package com.codestd.spring.cxf.ws;import javax.jws.WebService;import com.codestd.spring.cxf.annotation.Endpoint;/*** @author jaune(Wang Chengwei)* @since 1.0.0*/@Endpoint(address="HelloService", id = "HelloServiceEndpoint")@WebService(endpointInterface="com.codestd.spring.cxf.ws.HelloService")public class HelloServiceImpl implements HelloService{@Overridepublic String syHi(String name) {return "Hello "+name;}}

測(cè)試用例

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations={"classpath:applicationContext.xml"})public class InitializationTest {@Testpublic void test(){}}

在處理類中有一段代碼是將有@Endpoint注解的類都打印出來,所以如果類名被打印出來就表示配置正常了。

運(yùn)行測(cè)試用例

控制臺(tái)能夠看到

class com.codestd.spring.cxf.ws.HelloServiceImpl

通過以上內(nèi)容的介紹本次擴(kuò)展基本上就實(shí)現(xiàn)了。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 盐城市| 剑川县| 满城县| 疏勒县| 安岳县| 姜堰市| 剑川县| 安陆市| 北京市| 上犹县| 湖口县| 临泽县| 金寨县| 化州市| 电白县| 安吉县| 故城县| 广西| 贵州省| 兴海县| 黔西县| 铁力市| 宜兰县| 海丰县| 泽州县| 苍梧县| 大方县| 攀枝花市| 龙游县| 浮山县| 平安县| 贵南县| 拜城县| 河池市| 濉溪县| 民勤县| 读书| 绍兴县| 来凤县| 绿春县| 乐东|