@Autowire未正确注入Spring @Bean配置

时间:2013-09-18 06:11:17

标签: java spring dependency-injection autowired

我在spring-social上练习,当我在Eclipse中执行“Run as Junit Test”时,似乎userConnectionRepository未在以下代码中正确自动装配。在创建新的FacebookOffLine时,我在usersConnectionRepository上获得Null指针异常,尽管@Bean java创建代码中的断点显示它们似乎已正确创建。提前谢谢,

public class FacebookOffline {

    private Facebook fb;

    @Autowired
    private UsersConnectionRepository usersConnectionRepository;

    public FacebookOffline(User user) {
        super();

        ConnectionRepository cr = usersConnectionRepository.createConnectionRepository(user.getId());
        fb = cr.getPrimaryConnection(Facebook.class).getApi();
    }

}

这是测试代码:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {
        org.springframework.social.quickstart.config.MainConfig.class,
        org.springframework.social.quickstart.config.SocialConfig.class })
public class FacebookOfflineTest {

    @Test
    public void test1() {
        FacebookOffline essai = new FacebookOffline(new User("yves"));

Spring配置类改编自Keith Donald Quick Start Sample:

@Configuration
@ComponentScan(basePackages = "org.springframework.social.quickstart", excludeFilters = { @Filter(Configuration.class) })
@PropertySource("classpath:org/springframework/social/quickstart/config/application.properties")
public class MainConfig {

    @Bean
    public DataSource datasource() {
        DriverManagerDataSource toReturn = new DriverManagerDataSource("jdbc:mysql://localhost:3306/spring_social");
        toReturn.setDriverClassName("com.mysql.jdbc.Driver");
        toReturn.setUsername("spring");
        toReturn.setPassword("spring");
        return toReturn;

    }
}

@Configuration
public class SocialConfig {

    @Inject
    private Environment environment;

    @Inject
    private DataSource dataSource;

    @Bean
    public ConnectionFactoryLocator connectionFactoryLocator() {
        ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
        registry.addConnectionFactory(new FacebookConnectionFactory(environment
                .getProperty("facebook.clientId"), environment
                .getProperty("facebook.clientSecret")));
        return registry;
    }

@Bean
    public UsersConnectionRepository usersConnectionRepository() {
        JdbcUsersConnectionRepository repository = new JdbcUsersConnectionRepository(
                dataSource, connectionFactoryLocator(), Encryptors.noOpText());
        return repository;
    }

}

3 个答案:

答案 0 :(得分:7)

实际上这里有两个问题。

  1. Spring无法自动装配它无法控制的bean(即使用new创建)
  2. 构造函数中没有依赖项(在注入之前需要一个对象实例)
  3. 第一个可以通过让spring管理一个FacebookOffline实例来缓解(或者如果你需要多个实例使bean请求或会话作用域)。

    第二个有点难,但可以通过使用@PostConstruct注释的方法(或通过从春天实施InitializingBean来解决)。

答案 1 :(得分:2)

你做了

FacebookOffline essai = new FacebookOffline(new User("yves"));

这意味着,Spring没有管理这个essai实例,因此spring无法自动装配essai中的任何变量。

您必须在FacebookOffline中创建SocialConfig的bean。

然后你可以

/* ... */
public class FacebookOfflineTest {

@Autowired
ApplicationContext context;

@Test
public void test1() {
    FacebookOffline essai = context.getBean(FacebookOffline.class);

OR

 /* ... */
public class FacebookOfflineTest {

@Autowired
FacebookOffline essai;

@Test
public void test1() {
    // You can use essai now

此外,您需要更新FacebookOffline,因为构造函数中没有依赖项。

public class FacebookOffline {

private Facebook fb;

@Autowired
private UsersConnectionRepository usersConnectionRepository;

public FacebookOffline(User user) {
    super();  
}

@PostConstruct
void loadFacebook() {
    ConnectionRepository cr =       usersConnectionRepository.createConnectionRepository(user.getId());
     fb = cr.getPrimaryConnection(Facebook.class).getApi();
   }
}

答案 2 :(得分:0)

Spring无法在您通过new创建的实例上自动装配字段,因为它不知道它。声明声明类型为FacebookOffline的bean。