【问题标题】:@Autowire failing with @Repository@Autowire 使用 @Repository 失败
【发布时间】:2013-11-08 10:02:00
【问题描述】:

我无法使@Autowire 注释与@Repository 注释类一起工作。

我有一个界面:

public interface AccountRepository {
    public Account findByUsername(String username);
    public Account findById(long id);
    public Account save(Account account);
}

实现接口的类用@Repository注解

@Repository
public class AccountRepositoryImpl implements AccountRepository {
    public Account findByUsername(String username){
        //Implementing code
    }
    public Account findById(long id){
        //Implementing code            
    }
    public Account save(Account account){
        //Implementing code
    }
}

在另一个类中,我需要使用此存储库通过用户名查找帐户,因此我使用自动装配,但我正在检查它是否有效并且 accountRepository 实例始终为空

@Component
public class FooClass {
    @Autowired
    private AccountRepository accountRepository;

    ...

    public barMethod(){
        logger.debug(accountRepository == null ? "accountRepository is NULL" : "accountRepository IS NOT NULL");
    }
}

我还设置了要扫描组件的包 (sessionFactory.setPackagesToScan(new String [] {"com.foo.bar"});),它会自动装配其他带有 @Component 注释的类,但在这个带有 @Repository 注释的类中,它始终为空。

我错过了什么吗?

【问题讨论】:

  • 您如何获得对FooClass 的引用?你是说FooClass foo = new FooClass();
  • 你发现了问题,我得到了一个 new 的引用而不是自动装配。如果您想接受它作为正确的回复,请发布回复。真的谢谢!

标签: spring annotations repository autowired


【解决方案1】:

您的问题很可能是您自己使用new 实例化bean,因此Spring 没有意识到这一点。而是注入 bean,或者制作 bean @Configurable 并使用 AspectJ。

【讨论】:

    【解决方案2】:

    您似乎没有配置要启用的 Spring 注释。我建议您查看您的组件扫描注释。例如在 Java 配置应用程序中:

    @ComponentScan(basePackages = { "com.foo" })
    

    ... 或 XML 配置:

    <context:annotation-config />
    <context:component-scan base-package="com.foo" />
    

    如果您的 FooClass 不在该配置中定义的基本包下,则 @Autowired 将被忽略。

    另外一点,我建议尝试 @Autowired(required = true) - 应该 导致您的应用程序在启动时失败,而不是等到您使用该服务抛出 NullPointerException .但是,如果没有配置注解,则​​不会失败。

    您应该使用 JUnit 测试来测试您的自动装配是否正确。

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(
        classes = MyConfig.class, 
        loader = AnnotationConfigContextLoader.class)
    public class AccountRepositoryTest {
    
        @Autowired
        private AccountRepository accountRepository;
    
        @Test
        public void shouldWireRepository() {
            assertNotNull(accountRepository);
        }
    
    }
    

    这应该表明您的基本配置是否正确。下一步,假设这是作为 Web 应用程序部署的,将检查您是否在 web.xml 和 foo-servlet.xml 配置中放置了正确的部分以触发 Spring 初始化。

    【讨论】:

    • 我添加了@ComponentScan(basePackages = { "com.foo" }),我的班级在这个包下。我也尝试添加&lt;context:annotation-config /&gt;,但它不起作用。
    【解决方案3】:

    FooClass 需要由 Spring 实例化才能管理他的依赖关系。 确保 FooClass 被实例化为 bean(@Component 或 @Service 注释,或 XML 声明)。

    编辑:sessionFactory.setPackagesToScan 正在寻找 JPA/Hibernate 注释,而 @Repository 是 Spring Context 注释。 AccountRepositoryImpl 应该在 Spring component-scan 范围内

    问候,

    【讨论】:

    • 我写帖子的时候弄错了,FooClass已经用@Component注解了,我会编辑问题添加它。确实感谢
    • 但是@Component 也是一个 Spring Context 注释,它可以与其他使用 Component 注释的类一起工作。
    • 但是AccountRepositoryImpl 在哪个包中?什么是春天context:component-scan?他们匹配吗?
    • 仅供参考 - 您无需将类注释为组件(或任何其他原型),即可在其中使用自动装配注释。并非应用程序中的所有内容都必须是 Spring bean。
    • 嗯...没有自定义上下文查找或 BeanFactory,无法看到 Spring 如何自动装配他不管理的对象。您是否有将 bean 注入非 bean 的 XML 示例?编辑:SpringBeanAutowiringSupport 也可以完成这项工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-29
    相关资源
    最近更新 更多