Spring如何找到匹配的bean?

时间:2016-11-14 04:50:26

标签: java spring

我在RedisConfiguration中声明了bean,例如RedisTemplate<Long, Permission>RedisTemplate<Long, Order>。 代码如下所示,

@Bean
public RedisTemplate<String, Order> orderRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
    RedisTemplate<String, Order> redisTemplate = new RedisTemplate<>();
    configure(redisTemplate, redisConnectionFactory);
    return redisTemplate;
}

@Bean
public RedisTemplate<String, Permission> permissionRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
    RedisTemplate<String, Permission> redisTemplate = new RedisTemplate<>();
    configure(redisTemplate, redisConnectionFactory);
    return redisTemplate;
}

默认情况下,声明的名称的名称是声明的方法的名称。 现在,我编写了一个测试代码,在TestController中声明了一个注释@Autowired的文件。 测试代码如下:

@Autowired
RedisTemplate<String, Permission> permissionTemplate;

然后,我访问了TestController。它工作正常。 但是,我在测试中有一个问题。 Spring如何找到在RedisConfiguration中声明的Bean并分配给permissionTemplate提交? 我们知道,在Java编译时删除了泛型类型, 所以Spring不可能通过Generic Type找到合适的Bean。 下一个可能性是Spring通过filedName找到声明的Bean。 为了批准我的建议,我修改了TestController中的字段,如下所示。

@Autowired
RedisTemplate<String, Permission> orderTemplate;

然后,我请求了TestController。它也工作得很好。测试表明Spring使用Generic Type来查找匹配的Bean。

Spring如何知道permissionTemplate的泛型类型?

1 个答案:

答案 0 :(得分:1)

是的,Java泛型有类型擦除,但泛型类型信息在字节码中仍然存在很多场景,如Field,返回类型和方法参数。 Spring使用这些信息来确定泛型类型信息,从而进行bean类型匹配。

演示在运行时可用的通用信息:

import java.lang.reflect.*;
public class Foo {
    private List<String> fooField;

    public static void main(String[] args) throws Exception{
        for (Field f : Foo.class.getDeclaredFields()) {
            if (f.getName().equals("fooField")) {
                System.out.println("Generic Types " + f.getGenericType());
                break;
            }
        }
    }
}

你应该看到输出:

Generic Types java.util.List<java.lang.String>