Spring-based scalable Schema-based custom configuration (2)

Source: Internet
Author: User

Spring-based scalable Schema-based custom configuration (2)

This chapter provides configuration support, annotation scanning, and other functions. For the core of this tutorial

Namespace support

To support namespaces, you must inherit fromNamespaceHandlerSupport.

Package com. codestd. spring. cxf. config. schema; import org. springframework. beans. factory. xml. namespaceHandlerSupport; import com. codestd. spring. cxf. config. endpointBeanProcessor;/*** processing namespace * @ author jaune (Wang Chengwei) * @ since 1.0.0 */public class WebServiceAnnotationNamespaceHandler extends NamespaceHandlerSupport {@ Override public void init () {// TODO Auto-generated method stub this. registerBeanDefinitionParser ("annotation-endpoint", new AnnotationBeanDefinitionParser (EndpointBeanProcessor. class ));}}

You can use the registerBeanDefinitionParser method to add configurations to Spring.annotation-endpointIs an element supported by the configuration.AnnotationBeanDefinitionParserIs the class for processing configuration.EndpointBeanProcessorYes@EndpointAnnotation Bean class, which will be described in detail later.

Processing Configuration

BeanDefinitionParser needs to be implemented

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;    }    @Override    public 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;    }}

For BeanDefinitionParser applications, see the official Spring documentation.

Bean registration tool
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;    @Override    public 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;    }}
Processing @ 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. classpathbeandefinition.pdf; 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 implements attributes, DisposableBean, BeanPostProcessor, ApplicationContextAware {private final String attributes = ","; private ApplicationContext applicationContext; private String annotationPackage; private String [] annotationPackages; private BeanRegistry beanRegistry; public void setAnnotationPackage (St Ring annotationPackage) {this. annotationPackage = annotationPackage; if (! StringUtils. isEmpty (this. annotationPackage) this. annotationPackages = this. annotationPackage. split (this. COMMA_SPLIT_PATTERN);} @ Override public void setApplicationContext (ApplicationContext applicationContext) throws BeansException {this. applicationContext = applicationContext; this. beanRegistry = new BeanRegistry (this. applicationContext) ;}@ Override public 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;} @ Override public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException {return bean;} @ Override public void destroy () throws Exception {}/*** whether the package matches * @ 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 ;}/ *** scan {@ link com. codestd. spring. cxf. annotation. endpoint} annotation */@ Override public void postProcessBeanFactory (ConfigurableListableBeanFactory beanFactory) throws BeansException {if (annotationPackage = null | annotationPackage. length () = 0) {return;} if (beanFactory instanceof BeanDefinitionRegistry) {describeandefinitionregistry = (BeanDefinitionRegistry) beanFactory; describeandefinitionregistry; true ); annotationTypeFilter filter = new AnnotationTypeFilter (Endpoint. class); program. addmediadefilter (filter); optional. scan (annotationPackages );}}}

Annotation scanning has been implemented here. Then you needpostProcessAfterInitializationMethod. AfterInitialization indicates that the Bean has been created and the attributes are injected.
postProcessBeforeInitializationIt is mainly used to inject attributes during Bean instantiation.

Extend Spring Recognition

First create spring. handlers in the META-INF of classpath, the content is as follows

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

In this file, specify which namespace needs to be processed by the class.
Then create spring. schemas

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

Specifies the location of the Sechma file. Spring will use the xsd file specified here to verify whether the configuration is correct.

Test

Create Interface

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);}

Implementation class

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{    @Override    public String syHi(String name) {        return "Hello "+name;    }}

Test Cases

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

There is a piece of code in the processing class that prints out all classes with @ Endpoint annotation, so if the class name is printed, the configuration is normal.
Run Test Cases
The console shows

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

This extension is basically implemented.

The content of this tutorial can be found in Chapter 42nd of Spring official documentation.

Note
This time, the WebService function has not been automatically released. This function is complicated and has not yet been implemented yet. If it is implemented, it will be added in the following blog post.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.