Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过调用处理程序注入服务_Java_Spring - Fatal编程技术网

Java 通过调用处理程序注入服务

Java 通过调用处理程序注入服务,java,spring,Java,Spring,Spring中是否有一种干净的方式(没有XML)将接口连接到调用处理程序?目前,我必须做如下工作: @Inject private ServiceProxyCreator services; private MyServiceInterface service; private MyServiceInterface getService() { if ( service == null ) service = services.createProxy( MyServiceI

Spring中是否有一种干净的方式(没有XML)将接口连接到调用处理程序?目前,我必须做如下工作:

@Inject
private ServiceProxyCreator services;

private MyServiceInterface service;

private MyServiceInterface getService() {
   if ( service == null )
      service = services.createProxy( MyServiceInterface.class );

   return service;
}
@SuppressWarnings( "unchecked" )
public <T> T createProxy( Class<T> type ) {
    JobRpcHandler handler = new JobRpcHandler();
    handler.setServiceName( type.getSimpleName() );
    return (T) Proxy.newProxyInstance(
        type.getClassLoader(), new Class[]{type}, handler );
}
其中#createProxy只是以下内容的实现:

@Inject
private ServiceProxyCreator services;

private MyServiceInterface service;

private MyServiceInterface getService() {
   if ( service == null )
      service = services.createProxy( MyServiceInterface.class );

   return service;
}
@SuppressWarnings( "unchecked" )
public <T> T createProxy( Class<T> type ) {
    JobRpcHandler handler = new JobRpcHandler();
    handler.setServiceName( type.getSimpleName() );
    return (T) Proxy.newProxyInstance(
        type.getClassLoader(), new Class[]{type}, handler );
}
使用以某种方式定制的注入,我不知道如何在幕后创建代理,而不必调用#createProxy

关于更优雅的方法有什么建议吗?

请看。你可以这样写你自己的:

public class ServiceProxyFactoryBean implements FactoryBean<Object>
    private Class<T> type;

    public DutySetFactoryBean(Class<?> type) {
        this.type = type;
    }

    @Override
    public synchronized Object getObject() {
        JobRpcHandler handler = new JobRpcHandler();
        handler.setServiceName(type.getSimpleName());
        return Proxy.newProxyInstance(type.getClassLoader(), new Class[]{type}, handler);
    }

    @Override
    public Class<?> getObjectType() {
        return type;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

如果要为类路径中的所有带注释的接口自动创建代理,可以定义自己的代理。在这里,您必须使用以下模式扫描类路径:

MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
Resource[] resources = patternResolver.getResources(
        "classpath*:" + packageName.replace('.', '/') + "/**/*.class");
for (Resource resource : resources) {
    MetadataReader reader = metadataReaderFactory.getMetadataReader(resource);
    if (!reader.getAnnotationMetadata().isAnnotated(
            MyProxyAnnotation.class.getName())) {
        continue;
    }
    Class<?> cls = Class.forName(reader.getClassMetadata().getClassName(), true,
            resourceLoader.getClassLoader());
    String factoryBeanName = createNewName();
    BeanDefinitionBuilder bdb = BeanDefinitionBuilder.genericBeanDefinition(
            ServiceProxyFactoryBean.class);
    bdb.addConstructorArgValue(cls);
    registry.registerBeanDefinition(factoryBeanName, bdb.getBeanDefinition());
    bdb = BeanDefinitionBuilder.genericBeanDefinition(cls);
    bdb.setFactoryBean(factoryBeanName, "getBean");
    registry.registerBeanDefinition(createNewName(), bdb.getBeanDefinition());
}

就这些。不需要配置


我不确定这段代码是否有效,甚至无法编译。这不是最终的解决方案,只是一种你应该朝着的一般方式。所以您应该进行一些研究和调试。

我甚至不知道为什么要使用FactoryBean。我的意思是,如果我必须为每个类在一个配置类上创建一个Bean方法,那么我就不能在myservicebean方法中创建代理吗?我从工厂得到了什么?我希望有一种方法可以做到这一点,而不必为每个远程接口创建bean方法。但我也不能完全理解您的示例。@user1888440,如果我理解您的意思,您不想手动注册这些bean吗?与原型(@Component和其他)非常相似。所以,你们可以轻轻地伸展弹簧来为你们做这件事。我编辑了我的答案,并在那里添加了你应该如何做的描述。
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
Resource[] resources = patternResolver.getResources(
        "classpath*:" + packageName.replace('.', '/') + "/**/*.class");
for (Resource resource : resources) {
    MetadataReader reader = metadataReaderFactory.getMetadataReader(resource);
    if (!reader.getAnnotationMetadata().isAnnotated(
            MyProxyAnnotation.class.getName())) {
        continue;
    }
    Class<?> cls = Class.forName(reader.getClassMetadata().getClassName(), true,
            resourceLoader.getClassLoader());
    String factoryBeanName = createNewName();
    BeanDefinitionBuilder bdb = BeanDefinitionBuilder.genericBeanDefinition(
            ServiceProxyFactoryBean.class);
    bdb.addConstructorArgValue(cls);
    registry.registerBeanDefinition(factoryBeanName, bdb.getBeanDefinition());
    bdb = BeanDefinitionBuilder.genericBeanDefinition(cls);
    bdb.setFactoryBean(factoryBeanName, "getBean");
    registry.registerBeanDefinition(createNewName(), bdb.getBeanDefinition());
}
@MyProxyAnnotation
public interface MyServiceInterface {
    void foo();
}
@Component
public class MyBean {
    @Autowired
    private MyServiceInterface myService;
}