I have a redis util :
@Component
public class RedisUtil {
@Autowired
private StringRedisTemplate stringRedisTemplate;
public StringRedisTemplate getStringRedisTemplate() {
return this.stringRedisTemplate;
}
}
I want to use it in my custom class which I don’t want to be a component .
public class UserFeature {
public String result;
public String someMethod(){
var redisUtil = new RedisUtil();
var stringRedisTemplate = redisUtil.getStringRedisTemplate();
...
this.result = query_result_from_stringRedisTemplate;
}
}
When I use it like above , it raises a bean error .
What should I do ?
3
Answers
If you have a good reason for creating objects which shouldn’t be spring-managed, but still need to use spring beans, you can create a factory component which does the injection of spring beans into your non-spring object.
One nice feature of this approach is that it makes
UserFeature
easy to test — you can just pass its constructor a mockRedisUtil
.If for some reason you can’t turn
UserFeature
into a component, a general approach is to have a helper@Component
class that provides access to Spring beans from non-Spring POJOs.Then you can ask the Spring container for the
RedisUtil
bean instance as:This approach also lets you easily restrict which Spring beans can be accessed by non-Spring managed classes by having bean-specific getters in place of
getBean()
.As of Spring 4.3, classes don’t need to have any Spring annotations whatsoever to be eligible for injection. Simply include a single constructor. (Lombok
@RequiredArgsConstructor
can do this for you, and it’s built into Groovy and Kotlin.)