`

spring集成Hessian插件配置改成自动注入。

    博客分类:
  • J2EE
 
阅读更多

 原来的配置

<bean name="/UserService"
		class="org.springframework.remoting.caucho.HessianServiceExporter">
		<property name="serviceInterface" value="com.snailteam.service.UserService"></property>
		<property name="service" ref="userServiceImp"></property>
	</bean>

 

 <bean class="org.springframework.remoting.caucho.HessianProxyFactoryBean">   
                                <property name="serviceUrl" value="http://localhost:8080/api/service/UserService"></property>   
                                <property name="serviceInterface" value="com.snailteam.rpc.service.UserService"></property>   
                        </bean>  

 

现在的配置

 

<bean
		class="org.springframework.remoting.caucho.HessianExporterMapperScannerConfigurer">
		<property name="basePackage" value="com.snailteam.service" />
	</bean>

 

<bean
		class="org.springframework.remoting.caucho.HessianProxyMapperScannerConfigurer">
		<property name="serviceUrl" value="http://localhost:8080/api/service"></property>
		<property name="debug" value="false"></property>
		<property name="connectTimeout" value="3000"></property>
		<property name="readTimeout" value="30000"></property>
		<property name="basePackage" value="com.snailteam.rpc" />
	</bean>

 

 

代码

 

/** 
 * @author xiaofancn@gmail.com
 *  
 */

package org.springframework.remoting.caucho;  
  
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
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.classreading.SimpleMetadataReaderFactory;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.StringUtils;
import org.springframework.web.context.support.XmlWebApplicationContext;
  
/** 
 * @author xiaofancn@gmail.com 
 * @see Mybatis-spring MapperScannerConfigurer 
 */  
public class HessianExporterMapperScannerConfigurer implements  
        BeanDefinitionRegistryPostProcessor, InitializingBean,  
        ApplicationContextAware, BeanNameAware {  
    protected final Logger logger = LoggerFactory.getLogger(getClass());  
    private String serviceUrl;  
    private String basePackage;  
    private boolean debug;  
    private ApplicationContext applicationContext;  
    private Class<? extends Annotation> annotationClass;  
    private Class<?> markerInterface;  
    private String beanName;  
    private Map<String, String> implClassContextName = new HashMap<String, String>();  
  
    public void setDebug(boolean debug) {  
        this.debug = debug;  
    }  
  
    public void setImplClassContextName(Map<String, String> implClassContextName) {  
        this.implClassContextName = implClassContextName;  
    }  
  
    public Map<String, String> getImplClassContextName() {  
        return implClassContextName;  
    }  
  
    public void setApplicationContext(ApplicationContext applicationContext) {  
        this.applicationContext = applicationContext;  
    }  
  
    public void setBasePackage(String basePackage) {  
        this.basePackage = basePackage;  
    }  
  
    public void setServiceUrl(String serviceUrl) {  
        this.serviceUrl = serviceUrl;  
    }  
  
    public void setAnnotationClass(Class<? extends Annotation> annotationClass) {  
        this.annotationClass = annotationClass;  
    }  
  
    public void setMarkerInterface(Class<?> markerInterface) {  
        this.markerInterface = markerInterface;  
    }  
  
    @Override  
    public void postProcessBeanFactory(  
            ConfigurableListableBeanFactory beanFactory) throws BeansException {  
    }  
  
    @Override  
    public void postProcessBeanDefinitionRegistry(  
            BeanDefinitionRegistry beanDefinitionRegistry)  
            throws BeansException {  
        Scanner scanner = new Scanner(beanDefinitionRegistry);  
        scanner.setResourceLoader(this.applicationContext);  
        scanner.setBeanNameGenerator(new BeanNameGenerator() {  
  
            @Override  
            public String generateBeanName(BeanDefinition definition,  
                    BeanDefinitionRegistry registry) {  
                String beanName = definition.getBeanClassName().substring(  
                        definition.getBeanClassName().lastIndexOf(".") + 1);  
                return "/" + beanName;  
            }  
        });  
        scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage,  
                ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));  
    }  
  
    private final class Scanner extends ClassPathBeanDefinitionScanner {  
  
        public Scanner(BeanDefinitionRegistry registry) {  
            super(registry);  
        }  
  
        protected Set<BeanDefinitionHolder> doScan(String... basePackages) {  
            Set<BeanDefinitionHolder> beanDefinitions = super  
                    .doScan(basePackages);  
            if (beanDefinitions.isEmpty()) {  
                logger.warn("No R mapper was found in '"  
                        + HessianExporterMapperScannerConfigurer.this.basePackage  
                        + "' package. Please check your configuration.");  
            } else {  
                for (BeanDefinitionHolder holder : beanDefinitions) { 
                    GenericBeanDefinition definition = (GenericBeanDefinition) holder  
                            .getBeanDefinition();  
                    if (logger.isDebugEnabled()) {  
                        logger.debug("Creating MapperFactoryBean with name '"  
                                + holder.getBeanName() + "' and '"  
                                + definition.getBeanClassName()  
                                + "' mapperInterface");  
                    }  
  
                    /** 
                       
                     */  
                    try {
                    	//解析扫描的类
						Class cls = definition.resolveBeanClass(this.getResourceLoader().getClassLoader());
						definition.getPropertyValues().add("serviceInterface",  definition.getBeanClassName());  
						//通过class type,在spring root applaction获取对应的bean名字,取第一个。
	                    definition.getPropertyValues().add("service",new RuntimeBeanReference(applicationContext.getParent().getBeanNamesForType(cls)[0]));  
	                    definition.setBeanClass(HessianServiceExporter.class);  
                    } catch (ClassNotFoundException e) {
						logger.error(e);
					}
  
                }  
            }  
            return beanDefinitions;  
        }  
  
        @Override  
        protected boolean isCandidateComponent(  
                AnnotatedBeanDefinition beanDefinition) {  
            return (beanDefinition.getMetadata().isInterface() && beanDefinition  
                    .getMetadata().isIndependent());  
        }  
  
        @Override  
        protected boolean checkCandidate(String beanName,  
                BeanDefinition beanDefinition) throws IllegalStateException {  
            if (super.checkCandidate(beanName, beanDefinition)) {  
                return true;  
            } else {  
                logger.warn("Skipping HessianProxyFactoryBean with name '"  
                        + beanName + "' and '"  
                        + beanDefinition.getBeanClassName()  
                        + "' mapperInterface"  
                        + ". Bean already defined with the same name!");  
                return false;  
            }  
        }  
  
        @Override  
        protected void registerDefaultFilters() {  
            boolean acceptAllInterfaces = true;  
  
            // if specified, use the given annotation and / or marker interface  
            if (HessianExporterMapperScannerConfigurer.this.annotationClass != null) {  
                addIncludeFilter(new AnnotationTypeFilter(  
                        HessianExporterMapperScannerConfigurer.this.annotationClass));  
                acceptAllInterfaces = false;  
            }  
  
            // override AssignableTypeFilter to ignore matches on the actual  
            // marker interface  
            if (HessianExporterMapperScannerConfigurer.this.markerInterface != null) {  
                addIncludeFilter(new AssignableTypeFilter(  
                        HessianExporterMapperScannerConfigurer.this.markerInterface) {  
                    @Override  
                    protected boolean matchClassName(String className) {  
                        return false;  
                    }  
                });  
                acceptAllInterfaces = false;  
            }  
  
            if (acceptAllInterfaces) {  
                // default include filter that accepts all classes  
                addIncludeFilter(new TypeFilter() {  
                    public boolean match(MetadataReader metadataReader,  
                            MetadataReaderFactory metadataReaderFactory)  
                            throws IOException {  
                        return true;  
                    }  
                });  
            }  
  
            // exclude package-info.java  
            addExcludeFilter(new TypeFilter() {  
                public boolean match(MetadataReader metadataReader,  
                        MetadataReaderFactory metadataReaderFactory)  
                        throws IOException {  
                    String className = metadataReader.getClassMetadata()  
                            .getClassName();  
                    return className.endsWith("package-info");  
                }  
            });  
        }  
    }  
  
    @Override  
    public void setBeanName(String name) {  
    }  
  
    @Override  
    public void afterPropertiesSet() throws Exception {  
    }  
  
  
}  

 

 

 

 

package org.springframework.remoting.caucho;  
  
import static org.springframework.util.Assert.notNull;  
  
import java.io.IOException;  
import java.lang.annotation.Annotation;  
import java.util.Set;  
  
import org.springframework.beans.BeansException;  
import org.springframework.beans.factory.BeanNameAware;  
import org.springframework.beans.factory.InitializingBean;  
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;  
import org.springframework.beans.factory.config.BeanDefinition;  
import org.springframework.beans.factory.config.BeanDefinitionHolder;  
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;  
import org.springframework.beans.factory.support.BeanDefinitionRegistry;  
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;  
import org.springframework.beans.factory.support.GenericBeanDefinition;  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.ApplicationContextAware;  
import org.springframework.context.ConfigurableApplicationContext;  
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.AssignableTypeFilter;  
import org.springframework.core.type.filter.TypeFilter;  
import org.springframework.remoting.caucho.HessianProxyFactoryBean;  
import org.springframework.util.Assert;  
import org.springframework.util.StringUtils;  
  
/** 
 * @author xiaofancn@gmail.com 
 * @see Mybatis-spring MapperScannerConfigurer 
 */  
public class HessianProxyMapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {  
  
    private String serviceUrl;  
    private String basePackage;  
    private boolean debug;  
    private Integer connectTimeout;  
    private Integer readTimeout;  
    private ApplicationContext applicationContext;  
    private Class<? extends Annotation> annotationClass;  
    private Class<?> markerInterface;  
    private String beanName;  
  
    public void setConnectTimeout(Integer connectTimeout) {  
        this.connectTimeout = connectTimeout;  
    }  
  
    public void setDebug(boolean debug) {  
        this.debug = debug;  
    }  
  
    public void setReadTimeout(Integer readTimeout) {  
        this.readTimeout = readTimeout;  
    }  
  
    public void setApplicationContext(ApplicationContext applicationContext) {  
        this.applicationContext = applicationContext;  
    }  
  
    public void setBasePackage(String basePackage) {  
        this.basePackage = basePackage;  
    }  
  
    public void setServiceUrl(String serviceUrl) {  
        this.serviceUrl = serviceUrl;  
    }  
  
    public void setAnnotationClass(Class<? extends Annotation> annotationClass) {  
        this.annotationClass = annotationClass;  
    }  
  
    public void setMarkerInterface(Class<?> markerInterface) {  
        this.markerInterface = markerInterface;  
    }  
  
    @Override  
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {  
  
    }  
  
    @Override  
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {  
        Scanner scanner = new Scanner(beanDefinitionRegistry);  
        scanner.setResourceLoader(this.applicationContext);  
        scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));  
    }  
  
    /** 
     * org.springframework.remoting.caucho.HessianProxyFactoryBean 
     */  
  
    private final class Scanner extends ClassPathBeanDefinitionScanner {  
  
        public Scanner(BeanDefinitionRegistry registry) {  
            super(registry);  
        }  
  
        protected Set<BeanDefinitionHolder> doScan(String... basePackages) {  
            Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);  
            if (beanDefinitions.isEmpty()) {  
                logger.warn("No R mapper was found in '" + HessianProxyMapperScannerConfigurer.this.basePackage + "' package. Please check your configuration.");  
            } else {  
                for (BeanDefinitionHolder holder : beanDefinitions) {  
                    GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();  
  
                    if (logger.isDebugEnabled()) {  
                        logger.debug("Creating MapperFactoryBean with name '" + holder.getBeanName() + "' and '" + definition.getBeanClassName() + "' mapperInterface");  
                    }  
  
                    /** 
                        <bean class="org.springframework.remoting.caucho.HessianProxyFactoryBean">   
                                <property name="serviceUrl" value="http://localhost:8080/api/service/UserService"></property>   
                                <property name="serviceInterface" value="com.snailteam.rpc.service.UserService"></property>   
                        </bean>  
                     */  
                      
                    definition.getPropertyValues().add("serviceInterface", definition.getBeanClassName());  
                    String beanName = definition.getBeanClassName().substring(definition.getBeanClassName().lastIndexOf(".")+1);  
                    Assert.notNull(serviceUrl, "HessianProxyMapperScannerConfigurer serviceUrl must not be null");  
                    definition.setBeanClass(HessianProxyFactoryBean.class);  
                    definition.getPropertyValues().add("serviceUrl", HessianProxyMapperScannerConfigurer.this.serviceUrl+"/"+beanName);  
                    definition.getPropertyValues().add("debug", HessianProxyMapperScannerConfigurer.this.debug);  
                    definition.getPropertyValues().add("readTimeout", HessianProxyMapperScannerConfigurer.this.readTimeout);  
  
                    // serviceInterface  
  
                }  
            }  
            return beanDefinitions;  
        }  
  
        @Override  
        protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {  
            return (beanDefinition.getMetadata().isInterface() && beanDefinition.getMetadata().isIndependent());  
        }  
  
        @Override  
        protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException {  
            if (super.checkCandidate(beanName, beanDefinition)) {  
                return true;  
            } else {  
                logger.warn("Skipping HessianProxyFactoryBean with name '" + beanName + "' and '" + beanDefinition.getBeanClassName() + "' mapperInterface" + ". Bean already defined with the same name!");  
                return false;  
            }  
        }  
  
        @Override  
        protected void registerDefaultFilters() {  
            boolean acceptAllInterfaces = true;  
  
            // if specified, use the given annotation and / or marker interface  
            if (HessianProxyMapperScannerConfigurer.this.annotationClass != null) {  
                addIncludeFilter(new AnnotationTypeFilter(HessianProxyMapperScannerConfigurer.this.annotationClass));  
                acceptAllInterfaces = false;  
            }  
  
            // override AssignableTypeFilter to ignore matches on the actual  
            // marker interface  
            if (HessianProxyMapperScannerConfigurer.this.markerInterface != null) {  
                addIncludeFilter(new AssignableTypeFilter(HessianProxyMapperScannerConfigurer.this.markerInterface) {  
                    @Override  
                    protected boolean matchClassName(String className) {  
                        return false;  
                    }  
                });  
                acceptAllInterfaces = false;  
            }  
  
            if (acceptAllInterfaces) {  
                // default include filter that accepts all classes  
                addIncludeFilter(new TypeFilter() {  
                    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {  
                        return true;  
                    }  
                });  
            }  
              
            // exclude package-info.java  
            addExcludeFilter(new TypeFilter() {  
                public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {  
                    String className = metadataReader.getClassMetadata().getClassName();  
                    return className.endsWith("package-info");  
                }  
            });  
        }  
    }  
  
    @Override  
    public void setBeanName(String name) {  
        this.beanName = name;  
    }  
  
    @Override  
    public void afterPropertiesSet() throws Exception {  
        notNull(this.basePackage, "Property 'basePackage' is required");  
    }  
  
}  

 

 

package org.springframework.remoting.caucho;

/** 
 * @author xiaofancn@gmail.com
 * @version 创建时间:2017-2-14 下午6:18:59 
 * 类说明 
 */

import java.lang.reflect.Field;

import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.support.AopUtils;

public class AopTargetUtils {

	/**
	 * 获取 目标对象
	 * 
	 * @param proxy
	 *            代理对象
	 * @return
	 * @throws Exception
	 */
	public static Object getTarget(Object proxy) throws Exception {

		if (!AopUtils.isAopProxy(proxy)) {
			return proxy;// 不是代理对象
		}

		if (AopUtils.isJdkDynamicProxy(proxy)) {
			return getJdkDynamicProxyTargetObject(proxy);
		} else { // cglib
			return getCglibProxyTargetObject(proxy);
		}

	}

	private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
		Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
		h.setAccessible(true);
		Object dynamicAdvisedInterceptor = h.get(proxy);

		Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
		advised.setAccessible(true);

		Object target = ((AdvisedSupport) advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();

		return target;
	}

	private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
		Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
		h.setAccessible(true);
		AopProxy aopProxy = (AopProxy) h.get(proxy);

		Field advised = aopProxy.getClass().getDeclaredField("advised");
		advised.setAccessible(true);

		Object target = ((AdvisedSupport) advised.get(aopProxy)).getTargetSource().getTarget();

		return target;
	}

}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics