String之——注解发布RMI/HTTPInvoker/Hessian/Burlap服务

来源:互联网 发布:淘宝客返利 编辑:程序博客网 时间:2024/04/30 02:33

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/69478950

使用自定义的spring注解标签发布RMI/HTTPInvoker/Hessian/Burlap远程服务

1.依赖jar的pom.xml配置

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.slimsmart.spring.rpc.annotation.demo</groupId><artifactId>spring-rpc-annotation-demo</artifactId><version>1.0.0</version><packaging>jar</packaging><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.7</version><scope>test</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.0.9.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>4.0.9.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>4.0.9.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>4.0.9.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>4.0.9.RELEASE</version></dependency><dependency><groupId>com.caucho</groupId><artifactId>hessian</artifactId><version>4.0.38</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>4.0.9.RELEASE</version></dependency><dependency><groupId>org.eclipse.jetty</groupId><artifactId>jetty-webapp</artifactId><version>8.1.3.v20120416</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.8.5</version></dependency></dependencies><build>        <plugins>            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-compiler-plugin</artifactId>                <version>2.0.2</version>                <configuration>                    <source>1.6</source>                    <target>1.6</target>                </configuration>            </plugin>            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-eclipse-plugin</artifactId>                <version>2.9</version>                <configuration>                    <downloadSources>true</downloadSources>                    <downloadJavadocs>true</downloadJavadocs>                </configuration>            </plugin>        </plugins>    </build></project>

2.改造spring,使其支持注解发布不同服务

1)定义远程发布服务注解

RemoteService.Java
package org.springframework.remoting.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.stereotype.Component;/** * 远程发布注解RemoteService */@Target({ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface RemoteService {    ServiceType serviceType() default ServiceType.HTTP;    Class<?> serviceInterface();}

2)RmiServiceProperty.java

RemoteService辅助标签,在发布RMI服务时,用来指定RMI服务发布的端口。
package org.springframework.remoting.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import java.rmi.registry.Registry;import org.springframework.stereotype.Component;/** * RemoteService辅助标签,在发布RMI服务时,用来指定RMI服务发布的端口。 */@Target({ ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface RmiServiceProperty {    int registryPort() default Registry.REGISTRY_PORT;}

3)定义发布服务的类型枚举

package org.springframework.remoting.annotation;/** * ServiceType,指定发布服务的类型 */public enum ServiceType {    HTTP, BURLAP, HESSIAN, RMI}

4)注解解析实现

ServiceAnnotationBeanPostProcessor.java
package org.springframework.factory.annotation;import java.rmi.RemoteException;import org.springframework.beans.BeansException;import org.springframework.beans.FatalBeanException;import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;import org.springframework.core.Ordered;import org.springframework.core.PriorityOrdered;import org.springframework.core.annotation.AnnotationUtils;import org.springframework.remoting.annotation.RemoteService;import org.springframework.remoting.annotation.RmiServiceProperty;import org.springframework.remoting.annotation.ServiceType;import org.springframework.remoting.caucho.BurlapServiceExporter;import org.springframework.remoting.caucho.HessianServiceExporter;import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;import org.springframework.remoting.rmi.RmiServiceExporter;/** * 解析RemoteService注解标签,发布服务 */@SuppressWarnings("deprecation")public class ServiceAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements PriorityOrdered {private int order = Ordered.LOWEST_PRECEDENCE - 1;@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {RemoteService service = AnnotationUtils.findAnnotation(bean.getClass(), RemoteService.class);Object resultBean = bean;if (null != service) {//HttpInvoker 服务发布if (ServiceType.HTTP == service.serviceType()) {if (!beanName.startsWith("/")) {throw new FatalBeanException("Exception initializing  HttpInvokerService for " + beanName + ",beanName should bean start with \"/\".");}HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();httpInvokerServiceExporter.setServiceInterface(service.serviceInterface());httpInvokerServiceExporter.setService(bean);httpInvokerServiceExporter.afterPropertiesSet();resultBean = httpInvokerServiceExporter;//Hessian 服务发布} else if (ServiceType.HESSIAN == service.serviceType()) {if (!beanName.startsWith("/")) {throw new FatalBeanException("Exception initializing  HessianService for " + beanName + ",beanName should bean start with \"/\".");}HessianServiceExporter hessianServiceExporter = new HessianServiceExporter();hessianServiceExporter.setServiceInterface(service.serviceInterface());hessianServiceExporter.setService(bean);hessianServiceExporter.afterPropertiesSet();resultBean = hessianServiceExporter;//Burlap 服务发布} else if (ServiceType.BURLAP == service.serviceType()) {if (!beanName.startsWith("/")) {throw new FatalBeanException("Exception initializing BurlapService for " + beanName + ",beanName should bean start with \"/\".");}BurlapServiceExporter burlapServiceExporter = new BurlapServiceExporter();burlapServiceExporter.setServiceInterface(service.serviceInterface());burlapServiceExporter.setService(bean);burlapServiceExporter.afterPropertiesSet();resultBean = burlapServiceExporter;    //RIM 服务发布} else if (ServiceType.RMI == service.serviceType()) {RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();rmiServiceExporter.setServiceInterface(service.serviceInterface());rmiServiceExporter.setService(bean);RmiServiceProperty rmiServiceProperty = bean.getClass().getAnnotation(RmiServiceProperty.class);if (rmiServiceProperty != null) {rmiServiceExporter.setRegistryPort(rmiServiceProperty.registryPort());}String serviceName = beanName;if (serviceName.startsWith("/")) {serviceName = serviceName.substring(1);}rmiServiceExporter.setServiceName(serviceName);try {rmiServiceExporter.afterPropertiesSet();} catch (RemoteException remoteException) {throw new FatalBeanException("Exception initializing RmiServiceExporter", remoteException);}resultBean = rmiServiceExporter;}}return resultBean;}@Overridepublic int getOrder() {return order;}}

5)重写AnnotationConfigUtils类

重写spring注解配置工具类AnnotationConfigUtils.java 需与spring的在同一包目录
/* * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.springframework.context.annotation;import java.util.Collections;import java.util.LinkedHashSet;import java.util.Map;import java.util.Set;import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;import org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor;import org.springframework.beans.factory.config.BeanDefinition;import org.springframework.beans.factory.config.BeanDefinitionHolder;import org.springframework.beans.factory.support.AbstractBeanDefinition;import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.beans.factory.support.DefaultListableBeanFactory;import org.springframework.beans.factory.support.RootBeanDefinition;import org.springframework.context.support.GenericApplicationContext;import org.springframework.core.annotation.AnnotationAttributes;import org.springframework.core.annotation.AnnotationAwareOrderComparator;import org.springframework.core.type.AnnotatedTypeMetadata;import org.springframework.core.type.AnnotationMetadata;import org.springframework.factory.annotation.ServiceAnnotationBeanPostProcessor;import org.springframework.util.ClassUtils;/** * Utility class that allows for convenient registration of common * {@link org.springframework.beans.factory.config.BeanPostProcessor} and * {@link org.springframework.beans.factory.config.BeanFactoryPostProcessor} * definitions for annotation-based configuration. Also registers a common * {@link org.springframework.beans.factory.support.AutowireCandidateResolver}. * * @author Mark Fisher * @author Juergen Hoeller * @author Chris Beams * @author Phillip Webb * @since 2.5 * @see ContextAnnotationAutowireCandidateResolver * @see CommonAnnotationBeanPostProcessor * @see ConfigurationClassPostProcessor * @see org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor * @see org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor * @see org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor *///重写Spring框架 AnnotationConfigUtils,与spring相同包目录public class AnnotationConfigUtils {/** * The bean name of the internally managed Configuration annotation processor. */public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.factory.annotation.internalConfigurationAnnotationProcessor";/*** * 定义注解解析实现 */public static final String SERVICE_ANNOTATION_PROCESSOR_BEAN_NAME = "org.springframework.remoting.ServiceAnnotationBeanPostProcessor";/** * The bean name of the internally managed BeanNameGenerator for use when processing * {@link Configuration} classes. Set by {@link AnnotationConfigApplicationContext} * and {@code AnnotationConfigWebApplicationContext} during bootstrap in order to make * any custom name generation strategy available to the underlying * {@link ConfigurationClassPostProcessor}. * @since 3.1.1 */public static final String CONFIGURATION_BEAN_NAME_GENERATOR ="org.springframework.context.annotation.internalConfigurationBeanNameGenerator";/** * The bean name of the internally managed Autowired annotation processor. */public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalAutowiredAnnotationProcessor";/** * The bean name of the internally managed Required annotation processor. */public static final String REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalRequiredAnnotationProcessor";/** * The bean name of the internally managed JSR-250 annotation processor. */public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalCommonAnnotationProcessor";/** * The bean name of the internally managed JPA annotation processor. */public static final String PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalPersistenceAnnotationProcessor";private static final String PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME ="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor";/** * The bean name of the internally managed Scheduled annotation processor. * <p>ATTENTION:</p> This constant is meant for internal use only. The value is stable * but don't rely on the presence of this constant declaration; rather copy the value. */public static final String SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalScheduledAnnotationProcessor";/** * The bean name of the internally managed Async annotation processor. * <p>ATTENTION:</p> This constant is meant for internal use only. The value is stable * but don't rely on the presence of this constant declaration; rather copy the value. */public static final String ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalAsyncAnnotationProcessor";/** * The bean name of the internally managed AspectJ async execution aspect. * <p>ATTENTION:</p> This constant is meant for internal use only. The value is stable * but don't rely on the presence of this constant declaration; rather copy the value. */public static final String ASYNC_EXECUTION_ASPECT_BEAN_NAME ="org.springframework.scheduling.config.internalAsyncExecutionAspect";/** * The class name of the AspectJ async execution aspect. * <p>ATTENTION:</p> This constant is meant for internal use only. The value is stable * but don't rely on the presence of this constant declaration; rather copy the value. */public static final String ASYNC_EXECUTION_ASPECT_CLASS_NAME ="org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect";/** * The name of the AspectJ async execution aspect @{@code Configuration} class. * <p>ATTENTION:</p> This constant is meant for internal use only. The value is stable * but don't rely on the presence of this constant declaration; rather copy the value. */public static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME ="org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";/** * The bean name of the internally managed cache advisor. * <p>ATTENTION:</p> This constant is meant for internal use only. The value is stable * but don't rely on the presence of this constant declaration; rather copy the value. */public static final String CACHE_ADVISOR_BEAN_NAME ="org.springframework.cache.config.internalCacheAdvisor";/** * The bean name of the internally managed cache aspect. * <p>ATTENTION:</p> This constant is meant for internal use only. The value is stable * but don't rely on the presence of this constant declaration; rather copy the value. */public static final String CACHE_ASPECT_BEAN_NAME ="org.springframework.cache.config.internalCacheAspect";/** * The class name of the AspectJ caching aspect. * <p>ATTENTION:</p> This constant is meant for internal use only. The value is stable * but don't rely on the presence of this constant declaration; rather copy the value. */public static final String CACHE_ASPECT_CLASS_NAME ="org.springframework.cache.aspectj.AnnotationCacheAspect";/** * The name of the AspectJ caching aspect @{@code Configuration} class. * <p>ATTENTION:</p> This constant is meant for internal use only. The value is stable * but don't rely on the presence of this constant declaration; rather copy the value. */public static final String CACHE_ASPECT_CONFIGURATION_CLASS_NAME ="org.springframework.cache.aspectj.AspectJCachingConfiguration";private static final boolean jsr250Present =ClassUtils.isPresent("javax.annotation.Resource", AnnotationConfigUtils.class.getClassLoader());private static final boolean jpaPresent =ClassUtils.isPresent("javax.persistence.EntityManagerFactory", AnnotationConfigUtils.class.getClassLoader()) &&ClassUtils.isPresent(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, AnnotationConfigUtils.class.getClassLoader());/** * Register all relevant annotation post processors in the given registry. * @param registry the registry to operate on */public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {registerAnnotationConfigProcessors(registry, null);}/** * Register all relevant annotation post processors in the given registry. * @param registry the registry to operate on * @param source the configuration source element (already extracted) * that this registration was triggered from. May be {@code null}. * @return a Set of BeanDefinitionHolders, containing all bean definitions * that have actually been registered by this call */public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);if (beanFactory != null) {if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);}if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());}}Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);/** * 非ServiceAnnotationBeanPostProcessor类处理 */if (!registry.containsBeanDefinition(SERVICE_ANNOTATION_PROCESSOR_BEAN_NAME)) {      RootBeanDefinition def = new RootBeanDefinition(ServiceAnnotationBeanPostProcessor.class);      def.setSource(source);      def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      beanDefs.add(registerPostProcessor(registry, def, SERVICE_ANNOTATION_PROCESSOR_BEAN_NAME)); }if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));}// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition();try {def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,AnnotationConfigUtils.class.getClassLoader()));}catch (ClassNotFoundException ex) {throw new IllegalStateException("Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);}def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));}return beanDefs;}private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);registry.registerBeanDefinition(beanName, definition);return new BeanDefinitionHolder(definition, beanName);}private static DefaultListableBeanFactory unwrapDefaultListableBeanFactory(BeanDefinitionRegistry registry) {if (registry instanceof DefaultListableBeanFactory) {return (DefaultListableBeanFactory) registry;}else if (registry instanceof GenericApplicationContext) {return ((GenericApplicationContext) registry).getDefaultListableBeanFactory();}else {return null;}}public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {processCommonDefinitionAnnotations(abd, abd.getMetadata());}static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {if (metadata.isAnnotated(Lazy.class.getName())) {abd.setLazyInit(attributesFor(metadata, Lazy.class).getBoolean("value"));}else if (abd.getMetadata() != metadata && abd.getMetadata().isAnnotated(Lazy.class.getName())) {abd.setLazyInit(attributesFor(abd.getMetadata(), Lazy.class).getBoolean("value"));}if (metadata.isAnnotated(Primary.class.getName())) {abd.setPrimary(true);}if (metadata.isAnnotated(DependsOn.class.getName())) {abd.setDependsOn(attributesFor(metadata, DependsOn.class).getStringArray("value"));}if (abd instanceof AbstractBeanDefinition) {AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd;if (metadata.isAnnotated(Role.class.getName())) {absBd.setRole(attributesFor(metadata, Role.class).getNumber("value").intValue());}if (metadata.isAnnotated(Description.class.getName())) {absBd.setDescription(attributesFor(metadata, Description.class).getString("value"));}}}static BeanDefinitionHolder applyScopedProxyMode(ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();if (scopedProxyMode.equals(ScopedProxyMode.NO)) {return definition;}boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);}static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, Class<?> annotationClass) {return attributesFor(metadata, annotationClass.getName());}static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, String annotationClassName) {return AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(annotationClassName, false));}static Set<AnnotationAttributes> attributesForRepeatable(AnnotationMetadata metadata,Class<?> containerClass, Class<?> annotationClass) {return attributesForRepeatable(metadata, containerClass.getName(), annotationClass.getName());}@SuppressWarnings("unchecked")static Set<AnnotationAttributes> attributesForRepeatable(AnnotationMetadata metadata,String containerClassName, String annotationClassName) {Set<AnnotationAttributes> result = new LinkedHashSet<AnnotationAttributes>();addAttributesIfNotNull(result, metadata.getAnnotationAttributes(annotationClassName, false));Map<String, Object> container = metadata.getAnnotationAttributes(containerClassName, false);if (container != null && container.containsKey("value")) {for (Map<String, Object> containedAttributes : (Map<String, Object>[]) container.get("value")) {addAttributesIfNotNull(result, containedAttributes);}}return Collections.unmodifiableSet(result);}private static void addAttributesIfNotNull(Set<AnnotationAttributes> result, Map<String, Object> attributes) {if (attributes != null) {result.add(AnnotationAttributes.fromMap(attributes));}}}

3.测试类

先使用jetty启动web服务,再通过客户端调用

ServerRunner.java

package cn.lyz.spring.rpc.annotation.demo;import org.eclipse.jetty.server.Connector;import org.eclipse.jetty.server.Server;import org.eclipse.jetty.server.nio.SelectChannelConnector;import org.eclipse.jetty.webapp.WebAppContext;import org.junit.AfterClass;import org.junit.BeforeClass;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/** * 使用jetty作为服务端,运行测试前,先启动startWebapp */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = { "classpath:applicationContext-test.xml"})public class ServerRunner {private static Server server;@BeforeClasspublic static void startWebapp() throws Exception {server = new Server();Connector connector = new SelectChannelConnector();connector.setPort(8080); //设置webapp端口server.addConnector(connector);WebAppContext webAppContext = new WebAppContext();//设置工程名称webAppContext.setContextPath("/remoting");//这是webapp目录webAppContext.setWar("src/main/webapp");server.setHandler(webAppContext);server.start();System.out.println("syetem start sucess.");}@AfterClasspublic static void stopWebapp() throws Exception {server.stop();}}

UserServiceTest.java

package cn.lyz.spring.rpc.annotation.demo;import org.junit.Test;import org.springframework.beans.factory.annotation.Autowired;/** * UserService测试类 */public class UserServiceTest extends ServerRunner{@Autowiredprivate UserService userService;@Test  public void getUser() {    System.out.println(userService.getUser("slim"));  }}

1 0
原创粉丝点击