Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.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 当ApplicationContext位于另一个上下文中时,Spring@Autowired失败_Java_Spring_Autowired_Applicationcontext - Fatal编程技术网

Java 当ApplicationContext位于另一个上下文中时,Spring@Autowired失败

Java 当ApplicationContext位于另一个上下文中时,Spring@Autowired失败,java,spring,autowired,applicationcontext,Java,Spring,Autowired,Applicationcontext,我正试图整合一个SDK,它通过Spring自己管理的上下文在内部使用Spring。我希望构建的jar是可用的,无论Spring是否在想要使用SDK的应用程序上使用 当它自己运行时,我有一些东西可以工作。但是,如果我尝试在另一个Spring上下文(在我的例子中是基于Spring引导的应用程序)中使用SDK,我会得到一个org.springframework.beans.factory.NoSuchBeanDefinitionException:没有类型为的合格bean异常 尽管我尽了最大的努力,但

我正试图整合一个SDK,它通过Spring自己管理的上下文在内部使用Spring。我希望构建的jar是可用的,无论Spring是否在想要使用SDK的应用程序上使用

当它自己运行时,我有一些东西可以工作。但是,如果我尝试在另一个Spring上下文(在我的例子中是基于Spring引导的应用程序)中使用SDK,我会得到一个
org.springframework.beans.factory.NoSuchBeanDefinitionException:没有类型为
的合格bean异常

尽管我尽了最大的努力,但我无法理解如何让它工作,或者我到底做错了什么。下面的类显示了我正在做的事情,org.example.testapp.MySDKTest失败并出现异常,而org.example.test.MySDKTest成功通过。抱歉,代码太多了,但我无法用简化的案例重现这个问题

SDK源代码

package org.example.mysdk;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import org.example.mysdk.MyService;
import org.example.mysdk.MyServiceConfiguration;

public final class MySDK {

    private static ApplicationContext applicationContext;

    public static <T extends MyService> T getService(Class<? extends MyService> clazz, MyServiceConfiguration configuration) {
        T tmp = (T) getApplicationContext().getBean(clazz);
        tmp.setConfiguration(configuration);
        return tmp;
    }

    private static ApplicationContext getApplicationContext() {
        if (applicationContext == null) {
            applicationContext = new AnnotationConfigApplicationContext(SpringContext.class);
        }
        return applicationContext;
    }
}

测试

第一次测试失败,出现
org.springframework.beans.factory.NoSuchBeanDefinitionException:没有类型为
的合格bean异常

package org.example.testapp;

import static org.junit.Assert.*;

import org.example.mysdk.MyServiceConfiguration;
import org.example.mysdk.MyServiceImpl1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = App.class, loader = AnnotationConfigContextLoader.class)
public class MySDKTest {

    @Autowired
    MyServiceImpl1 service;

    @Test
    public void test() {

        MyServiceConfiguration conf = service.getConfiguration();

        assertEquals(conf.getValue(), "this is the instance configuration");
    }

}

而且这个试验成功了,

package org.example.test;

import static org.junit.Assert.*;

import org.example.mysdk.MySDK;
import org.example.mysdk.MyServiceConfiguration;
import org.example.mysdk.MyServiceImpl1;
import org.junit.Test;

public class MySDKTest {

    @Test
    public void test() {

        MyServiceConfiguration configuration = new MyServiceConfiguration();
        configuration.setValue("this is the instance configuration");

        MyServiceImpl1 service = MySDK.getService(MyServiceImpl1.class, configuration);

        assertEquals(service.getConfiguration().getValue(), "this is the instance configuration");

    }

}

如果我用了完全错误的方法,我很高兴听到关于如何用不同的方式来做这件事的建议

您必须修改两个文件

首先
App.java
,它应该扫描
“org.example.mysdk”
包,在抽象类
MyService
中注入
myAutowiredService
,否则必须在
App.java
中创建。而且
MyServiceImpl
1bean的名称必须与
myServiceImpl1
不同,因为它会发生冲突

package org.example.testapp;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.example.mysdk.MySDK;
import org.example.mysdk.MyServiceConfiguration;
import org.example.mysdk.MyServiceImpl1;

@Configuration
@ComponentScan(basePackages = {
    "org.example.testapp", "org.example.mysdk"
})
public class App {

    @Bean
    public MyServiceImpl1 myServiceImpl() {

        MyServiceConfiguration configuration = new MyServiceConfiguration();
        configuration.setValue("this is the instance configuration");

        return MySDK.getService(MyServiceImpl1.class, configuration);
    }
}
其次,在
MySDKTest.java
中,应该插入
myservicecimpl
中创建的
App.java

import static org.junit.Assert.*;

import org.example.mysdk.MyServiceConfiguration;
import org.example.mysdk.MyServiceImpl1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = App.class, loader = AnnotationConfigContextLoader.class)
public class MySDKTest {

    @Autowired
    MyServiceImpl1 myServiceImpl;

    @Test
    public void createOxiAccountService() {     

        MyServiceConfiguration conf = myServiceImpl.getConfiguration();

        assertEquals(conf.getValue(), "this is the instance configuration");
    }

}

感谢@shazin的回答,我希望有两个完全独立的Spring上下文(基本上我不希望SDK用户知道/关心库在内部使用Spring)。有没有办法在两种情况下保持关注点的分离?
package org.example.mysdk;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = {
    "org.example.mysdk"
})
public class SpringContext {

}
package org.example.testapp;

import static org.junit.Assert.*;

import org.example.mysdk.MyServiceConfiguration;
import org.example.mysdk.MyServiceImpl1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = App.class, loader = AnnotationConfigContextLoader.class)
public class MySDKTest {

    @Autowired
    MyServiceImpl1 service;

    @Test
    public void test() {

        MyServiceConfiguration conf = service.getConfiguration();

        assertEquals(conf.getValue(), "this is the instance configuration");
    }

}
package org.example.testapp;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.example.mysdk.MySDK;
import org.example.mysdk.MyServiceConfiguration;
import org.example.mysdk.MyServiceImpl1;

@Configuration
@ComponentScan(basePackages = {
    "org.example.testapp"
})
public class App {

    @Bean
    public MyServiceImpl1 myServiceImpl1() {

        MyServiceConfiguration configuration = new MyServiceConfiguration();
        configuration.setValue("this is the instance configuration");

        return MySDK.getService(MyServiceImpl1.class, configuration);
    }
}
package org.example.test;

import static org.junit.Assert.*;

import org.example.mysdk.MySDK;
import org.example.mysdk.MyServiceConfiguration;
import org.example.mysdk.MyServiceImpl1;
import org.junit.Test;

public class MySDKTest {

    @Test
    public void test() {

        MyServiceConfiguration configuration = new MyServiceConfiguration();
        configuration.setValue("this is the instance configuration");

        MyServiceImpl1 service = MySDK.getService(MyServiceImpl1.class, configuration);

        assertEquals(service.getConfiguration().getValue(), "this is the instance configuration");

    }

}
package org.example.testapp;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.example.mysdk.MySDK;
import org.example.mysdk.MyServiceConfiguration;
import org.example.mysdk.MyServiceImpl1;

@Configuration
@ComponentScan(basePackages = {
    "org.example.testapp", "org.example.mysdk"
})
public class App {

    @Bean
    public MyServiceImpl1 myServiceImpl() {

        MyServiceConfiguration configuration = new MyServiceConfiguration();
        configuration.setValue("this is the instance configuration");

        return MySDK.getService(MyServiceImpl1.class, configuration);
    }
}
import static org.junit.Assert.*;

import org.example.mysdk.MyServiceConfiguration;
import org.example.mysdk.MyServiceImpl1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = App.class, loader = AnnotationConfigContextLoader.class)
public class MySDKTest {

    @Autowired
    MyServiceImpl1 myServiceImpl;

    @Test
    public void createOxiAccountService() {     

        MyServiceConfiguration conf = myServiceImpl.getConfiguration();

        assertEquals(conf.getValue(), "this is the instance configuration");
    }

}