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