diff --git a/dubbo-common/src/main/java/com/alibaba/dubbo/common/serialize/support/annotation/Optimizer.java b/dubbo-common/src/main/java/com/alibaba/dubbo/common/serialize/support/annotation/Optimizer.java new file mode 100644 index 00000000000..8332daf3730 --- /dev/null +++ b/dubbo-common/src/main/java/com/alibaba/dubbo/common/serialize/support/annotation/Optimizer.java @@ -0,0 +1,18 @@ +package com.alibaba.dubbo.common.serialize.support.annotation; + +import java.lang.annotation.*; + +/** + *

Created with IntelliJ IDEA.

+ *

User: Stony

+ *

Date: 2016/7/1

+ *

Time: 11:35

+ *

Version: 1.0

+ * 序列化优化注解扫描,注册到 + * @see com.alibaba.dubbo.common.serialize.support.SerializableClassRegistry + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Documented +public @interface Optimizer { +} diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/processor/OptimizerAnnotationRegistryPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/processor/OptimizerAnnotationRegistryPostProcessor.java new file mode 100644 index 00000000000..da8849633fd --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/processor/OptimizerAnnotationRegistryPostProcessor.java @@ -0,0 +1,73 @@ +package com.alibaba.dubbo.config.spring.processor; + +import com.alibaba.dubbo.common.serialize.support.SerializableClassRegistry; +import com.alibaba.dubbo.config.spring.scan.OptimizerScanner; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.Ordered; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +import java.util.Collections; +import java.util.List; + +/** + *

Created with IntelliJ IDEA.

+ *

User: Stony

+ *

Date: 2016/7/1

+ *

Time: 11:31

+ *

Version: 1.0

+ *

序列化XML优化配置

+ *
+ * <bean id="optimizerAnnotationScan" class="com.alibaba.dubbo.config.spring.processor.OptimizerAnnotationRegistryPostProcessor" >
+ *     <property name="basePackage" value="com.stone.beans" />
+ *  </bean>
+ * 
+ */ +public class OptimizerAnnotationRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor,InitializingBean,Ordered { + + private String basePackage; + public static final String OPTIMIZER_BEAN_LIST = "G_OPTIMIZER_BEAN_LIST"; + private List classes; + + @Override + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { + OptimizerScanner optimizerScanner = new OptimizerScanner(registry); + try { + classes = optimizerScanner.scanBeanClass(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS)); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + if(null != classes){ + for (Class c : classes) { + SerializableClassRegistry.registerClass(c); + } + } + } + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + if(classes != null) { + beanFactory.registerSingleton(OPTIMIZER_BEAN_LIST, classes); + }else{ + beanFactory.registerSingleton(OPTIMIZER_BEAN_LIST, Collections.EMPTY_LIST); + } + } + + public void setBasePackage(String basePackage) { + this.basePackage = basePackage; + } + + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE + 10; + } + + @Override + public void afterPropertiesSet() throws Exception { + Assert.notNull(this.basePackage, "property basePackage is required"); + } +} diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/scan/OptimizerScanner.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/scan/OptimizerScanner.java new file mode 100644 index 00000000000..e0782a24bbe --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/scan/OptimizerScanner.java @@ -0,0 +1,88 @@ +package com.alibaba.dubbo.config.spring.scan; + +import com.alibaba.dubbo.common.serialize.support.annotation.Optimizer; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.context.annotation.ClassPathBeanDefinitionScanner; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.core.type.classreading.MetadataReaderFactory; +import org.springframework.core.type.filter.AnnotationTypeFilter; +import org.springframework.core.type.filter.TypeFilter; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +/** + *

Created with IntelliJ IDEA.

+ *

User: Stony

+ *

Date: 2016/7/1

+ *

Time: 14:09

+ *

Version: 1.0

+ *

Optimizer注解扫描

+ */ +public class OptimizerScanner extends ClassPathBeanDefinitionScanner { + private volatile boolean isInit = false; + private final Object monitor = new Object(); + + /** + * 不加载默认的过滤器 + * @param registry bean 注册接口 + */ + public OptimizerScanner(BeanDefinitionRegistry registry) { + this(registry, false); + } + + /** + * + * @param registry bean 注册接口 + * @param b 是否默认过滤器加载 + */ + public OptimizerScanner(BeanDefinitionRegistry registry, boolean b) { + super(registry, b); + init(); + } + + public void init(){ + if(isInit){ + return; + } + setIncludeAnnotationConfig(true); + addIncludeFilter(new AnnotationTypeFilter(Optimizer.class)); + addExcludeFilter(new TypeFilter() { + @Override + public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { + String className = metadataReader.getClassMetadata().getClassName(); + return className.endsWith("package-info"); + } + }); + synchronized (this.monitor) { + this.isInit = true; + } + } + + /** + * 返回 Optimizer 注解类Class + * @param basePackages + * @return + * @throws ClassNotFoundException + */ + public List scanBeanClass(String... basePackages) throws ClassNotFoundException { + Assert.notEmpty(basePackages, "At least one base package must be specified"); + ClassLoader beanClassLoader = OptimizerScanner.class.getClassLoader(); + List beanClass = new LinkedList(); + for (String basePackage : basePackages) { + Set candidates = findCandidateComponents(basePackage); + for (BeanDefinition candidate : candidates) { + beanClass.add(resolveClassName(candidate.getBeanClassName(), beanClassLoader)); + } + } + return beanClass; + } + + protected Class resolveClassName(String className, ClassLoader beanClassLoader) throws ClassNotFoundException { + return ClassUtils.forName(className, beanClassLoader); + } +} diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/schema/DubboNamespaceHandler.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/schema/DubboNamespaceHandler.java index 4afe4a42828..887be4b7e6d 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/schema/DubboNamespaceHandler.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/schema/DubboNamespaceHandler.java @@ -52,6 +52,7 @@ public void init() { registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true)); registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false)); registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true)); + registerBeanDefinitionParser("optimizer", new OptimizerAnnotationBeanDefinitionParser()); } } \ No newline at end of file diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/schema/OptimizerAnnotationBeanDefinitionParser.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/schema/OptimizerAnnotationBeanDefinitionParser.java new file mode 100644 index 00000000000..27cec56cfb4 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/schema/OptimizerAnnotationBeanDefinitionParser.java @@ -0,0 +1,58 @@ +package com.alibaba.dubbo.config.spring.schema; + + +import com.alibaba.dubbo.common.serialize.support.SerializableClassRegistry; +import com.alibaba.dubbo.config.spring.scan.OptimizerScanner; +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.beans.factory.xml.XmlReaderContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +import java.util.LinkedList; +import java.util.List; + +/** + *

Created with IntelliJ IDEA.

+ *

User: Stony

+ *

Date: 2016/7/1

+ *

Time: 14:05

+ *

Version: 1.0

+ *

将Optimizer 注解类Class注册到SerializableClassRegistry中

+ */ +public class OptimizerAnnotationBeanDefinitionParser implements BeanDefinitionParser { + + public static final String OPTIMIZER_BEAN_LIST = "G_OPTIMIZER_BEAN_LIST"; + private List classes; + + @Override + public BeanDefinition parse(Element element, ParserContext parserContext) { + XmlReaderContext readerContext = parserContext.getReaderContext(); + OptimizerScanner optimizerScanner = new OptimizerScanner(readerContext.getRegistry()); + + try { + String basePackage = element.getAttribute("base-package"); + classes = optimizerScanner.scanBeanClass(StringUtils.tokenizeToStringArray(basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS)); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + if(null != classes){ + for (Class c : classes) { + SerializableClassRegistry.registerClass(c); + } + } + + RootBeanDefinition beanDefinition = new RootBeanDefinition(); + beanDefinition.setBeanClass(LinkedList.class); + beanDefinition.setLazyInit(false); + if (classes != null) { + beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, classes); + } + parserContext.getRegistry().registerBeanDefinition(OPTIMIZER_BEAN_LIST, beanDefinition); + return beanDefinition; + } +} diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd index d0168856cd4..2e7e75bdea4 100644 --- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd +++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd @@ -1178,5 +1178,14 @@ - + + + + + + + + + + \ No newline at end of file diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/facade/TOrder.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/facade/TOrder.java new file mode 100644 index 00000000000..843382fa368 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/facade/TOrder.java @@ -0,0 +1,41 @@ +package com.alibaba.dubbo.config.spring.facade; + + +import com.alibaba.dubbo.common.serialize.support.annotation.Optimizer; + +/** + *

Created with IntelliJ IDEA.

+ *

User: Stony

+ *

Date: 2016/7/4

+ *

Time: 10:19

+ *

Version: 1.0

+ */ +@Optimizer +public class TOrder { + int id; + String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "TOrder{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } +} diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/facade/TUser.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/facade/TUser.java new file mode 100644 index 00000000000..55d6c7b1a07 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/facade/TUser.java @@ -0,0 +1,41 @@ +package com.alibaba.dubbo.config.spring.facade; + + +import com.alibaba.dubbo.common.serialize.support.annotation.Optimizer; + +/** + *

Created with IntelliJ IDEA.

+ *

User: Stony

+ *

Date: 2016/7/4

+ *

Time: 10:19

+ *

Version: 1.0

+ */ +@Optimizer +public class TUser { + int id; + String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "TUser{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } +} diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/facade2/TAccount.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/facade2/TAccount.java new file mode 100644 index 00000000000..f459420777e --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/facade2/TAccount.java @@ -0,0 +1,40 @@ +package com.alibaba.dubbo.config.spring.facade2; + +import com.alibaba.dubbo.common.serialize.support.annotation.Optimizer; + +/** + *

Created with IntelliJ IDEA.

+ *

User: Stony

+ *

Date: 2016/7/5

+ *

Time: 12:00

+ *

Version: 1.0

+ */ +@Optimizer +public class TAccount { + int id; + String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "TAccount{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } +} diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/optimizer/OptimizerTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/optimizer/OptimizerTest.java new file mode 100644 index 00000000000..7a54a0e7609 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/optimizer/OptimizerTest.java @@ -0,0 +1,37 @@ +package com.alibaba.dubbo.config.spring.optimizer; + +import com.alibaba.dubbo.common.serialize.support.SerializableClassRegistry; +import com.alibaba.dubbo.config.spring.schema.OptimizerAnnotationBeanDefinitionParser; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + *

Created with IntelliJ IDEA.

+ *

User: Stony

+ *

Date: 2016/7/5

+ *

Time: 12:01

+ *

Version: 1.0

+ */ +public class OptimizerTest { + + @Test + public void test(){ + ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com/alibaba/dubbo/config/spring/spring-test-optimizer.xml"); + ctx.start(); + try{ + System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); + System.out.println("getRegisteredClasses : " + SerializableClassRegistry.getRegisteredClasses()); + System.out.println("OPTIMIZER_BEAN_LIST : " + ctx.getBean(OptimizerAnnotationBeanDefinitionParser.OPTIMIZER_BEAN_LIST)); + System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); + assertNotNull(SerializableClassRegistry.getRegisteredClasses()); + assertTrue(3==SerializableClassRegistry.getRegisteredClasses().size()); + } finally { + ctx.stop(); + ctx.close(); + } + } +} diff --git a/dubbo-config/dubbo-config-spring/src/test/resources/com/alibaba/dubbo/config/spring/spring-test-optimizer.xml b/dubbo-config/dubbo-config-spring/src/test/resources/com/alibaba/dubbo/config/spring/spring-test-optimizer.xml new file mode 100644 index 00000000000..01027b2aec6 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/test/resources/com/alibaba/dubbo/config/spring/spring-test-optimizer.xml @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file