结论:标注@Configuration(proxyBeanMethods = false)注解的配置类,类中被@Bean标注的方法将不会被spring通过CGLB代理,但是spring容器中还是有这个bean的,在spring容器中获取的bean(getBean()、@Autowired等方式获取)还是单例的,但是你通过直接调用方法,获取到的就会是一个新的bean
(1)先看 proxyBeanMethods = true (默认是true)的情况
java">@Configuration(proxyBeanMethods = true)
public class RedisConfig {@Bean("redisTemplate")public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<Object, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);// key 的 String 序列化采用 StringRedisSerializerStringRedisSerializer stringRedisSerializer = new StringRedisSerializer();template.setKeySerializer(stringRedisSerializer);template.setHashKeySerializer(stringRedisSerializer);// 使用 FastJsonRedisSerializer 来序列化和反序列化redis 的 value的值FastJsonRedisSerializer<Object> serializer = new FastJsonRedisSerializer<>(Object.class);FastJsonConfig fastJsonConfig = new FastJsonConfig();fastJsonConfig.setCharset(StandardCharsets.UTF_8);serializer.setFastJsonConfig(fastJsonConfig);template.setValueSerializer(serializer);template.setHashValueSerializer(serializer);template.afterPropertiesSet();return template;}
}
java"> @Autowiredprivate RedisTemplate<Object, Object> redisTemplate;@Autowiredprivate ApplicationContext applicationContext;@AutowiredRedisConnectionFactory redisConnectionFactory;@GetMapping("/sec")public void secKill() {System.out.println("spring容器中获取=====>" + redisTemplate);RedisConfig bean = applicationContext.getBean(RedisConfig.class);System.out.println( "spring容器中获取=====>" + bean);RedisTemplate<Object, Object> objectObjectRedisTemplate = bean.redisTemplate(redisConnectionFactory);System.out.println( "调用方法获取=====>" + objectObjectRedisTemplate);}
结果:
java">spring容器中获取=====>org.springframework.data.redis.core.RedisTemplate@1306c4b0
spring容器中获取=====>com.example.simplejobdemo.config.RedisConfig$$SpringCGLIB$$0@3410f434
调用方法获取=====>org.springframework.data.redis.core.RedisTemplate@1306c4b0
spring容器中获取=====>org.springframework.data.redis.core.RedisTemplate@1306c4b0
spring容器中获取=====>com.example.simplejobdemo.config.RedisConfig$$SpringCGLIB$$0@3410f434
调用方法获取=====>org.springframework.data.redis.core.RedisTemplate@1306c4b0
spring容器中获取=====>org.springframework.data.redis.core.RedisTemplate@1306c4b0
spring容器中获取=====>com.example.simplejobdemo.config.RedisConfig$$SpringCGLIB$$0@3410f434
调用方法获取=====>org.springframework.data.redis.core.RedisTemplate@1306c4b0
(2)将proxyBeanMethods = true 由 true 改成false
结果:
java">spring容器中获取=====>org.springframework.data.redis.core.RedisTemplate@2bc37a0a
spring容器中获取=====>com.example.simplejobdemo.config.RedisConfig@b18f3e8
调用方法获取=====>org.springframework.data.redis.core.RedisTemplate@7eb173e6
spring容器中获取=====>org.springframework.data.redis.core.RedisTemplate@2bc37a0a
spring容器中获取=====>com.example.simplejobdemo.config.RedisConfig@b18f3e8
调用方法获取=====>org.springframework.data.redis.core.RedisTemplate@4fbb2cfd
spring容器中获取=====>org.springframework.data.redis.core.RedisTemplate@2bc37a0a
spring容器中获取=====>com.example.simplejobdemo.config.RedisConfig@b18f3e8
调用方法获取=====>org.springframework.data.redis.core.RedisTemplate@68627132
可以看出从Spring容器中获取的依旧是单例Bean,而通过方法获取的是多实例的