Spring Bean注释名称属性的目的是什么?

时间:2015-05-07 17:19:30

标签: java spring annotations spring-annotations

我只是在学习spring,而且使用name属性作为字符串的注释配置非常奇怪。

@Bean(name = "com.my.injected.Service")
public InjectedService injectedService() {
    return injectedService;
}

这个名字是否类似于Spring Bean XML configuration id and class attributes

<bean id="..." class="...">
    <!-- collaborators and configuration for this bean go here -->
</bean>

为什么不是这个

@Bean(clazz = com.my.injected.Service.class)
public InjectedService injectedService() {
    return injectedService;
}

代替?

在这两种情况下,您完全符合路径的要求,实际使用该类可以让您的IDE更容易告诉您什么时候搞砸了。我知道XML配置是第一位的,当然它总是按字符串查找东西,所以这只是一个保留吗?使用字符串或使用.class的主要缺点是否有一些优势?

问题最初基于错误的前提。我编辑它来说明这个前提是什么,并让那些出现的新人不那么混乱。希望我这样做,使得给定的答案仍然完全适用;如果没有道歉。

2 个答案:

答案 0 :(得分:2)

@Bean注释旨在提供一个spring bean。要提供的bean的类型与您在return方法中定义的类/接口的类型相同。因此,不是声明返回方法中的具体类,而是返回顶层(抽象)类/接口。

想象一下这个案例:

public interface MyEntityDao {
    MyEntity get(String id);
}

@Repository
public class MyEntityDaoDatabaseImpl implements MyEntityDao {
    @Override
    public MyEntity get(String id) {
        /* implementation that goes to database every time */
    }
}

@Repository
public class MyEntityDaoCacheImpl implements MyEntityDao {
    @Override
    public MyEntity get(String id) {
        /* implementation that looks the data
           up in cache, never in database */
    }
}

@Configuration
public class MyAppConfiguration {
    @Bean
    public MyEntityDaoDatabaseImpl method1() {
        return new MyEntityDaoDatabaseImpl();
    }
    @Bean
    public MyEntityDaoCacheImpl method2() {
        return new MyEntityDaoCacheImpl();
    }
}

@Service
public class MyEntityService {
    @Autowired //what to inject here?
    MyEntityDao dao;
}

在上述情况下,提出的接口有两种实现方式。框架如何能够理解除名称之外使用哪种实现?

@Service
public class MyEntityService {
    @Autowired
    @Qualifier("properBeanNameToInject")
    MyEntityDao dao;
}

答案 1 :(得分:1)

Bean名称不一定与其类或甚至它实现的任何接口相关。这是一个名字,仅此而已。当您使用注释配置时,Spring会确定@Bean提供的确切类或接口与java代码的其余部分一样:通过代码中的完全限定名称或通过文件中指定的导入。在您的情况下,您可能在java文件的顶部有一个import com.my.injected.Service;语句。

您的示例使用完全限定的类名作为bean名称。这是你的选择。您可以使用任何其他标识符。如果您的代码提供的对象的名称与您的代码必须包含或使用的另一个第三方@Bean对象完全相同,则使用完全限定名称可能非常有用。但是,您可以轻松使用name = "myService"

bean名称可以帮助Spring(和应用程序程序员)区分同一个bean类的多个实例,因为你可以多次将同一个类部署为bean。如果只出现一个bean类型的实例,则事件不必手动为其命名:spring默认执行此操作。

如果您有几个具有相同类型或实现相同接口的bean,并且您想引用特定bean使用@Qualifier注释。