Using spring managed beans in an interface default method?


Staff member
Warning: I realize this <em>may</em> be an abuse of the intention behind spring beans and/or Java 8's default interface methods. What I'm looking for is specific and reasoned criticisms of why this might be an unsafe approach that I am failing to recognize.

I've defined a class that gives me static access to the running application context:

public class BeanAccessor implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    public static &lt;T&gt; T getSingleton(Class&lt;T&gt; clazz){
        return applicationContext.getBean(clazz);

    public static &lt;T&gt; T getSingleton(String beanName, Class&lt;T&gt; clazz){
        return applicationContext.getBean(beanName, clazz);

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        BeanAccessor.applicationContext = applicationContext;


I then am able to use those BeanAccessor methods inside of default interface methods in order to gain access to spring managed beans from inside the method.

I realize that this functionality could be achieved by implementing other classes and services rather than feeling a need to mix it into the current one (at least for the example below, I'm not actually doing anything with 'this'). This is partly an 'artistic' preference and I'm sure I'll continue to find other use cases.

Note that I am NOT trying to preserve state per instance like described here <a href="" rel="nofollow"></a> and I do recognize that there are dangers in doing that.

Here's an example usage:

public interface ClientAware {


    default ClientDetails clientDetails() {
        ClientDetailsService service = BeanAccessor.getSingleton(ClientDetailsService.class);
        return service.loadClientByClientId(SecurityUtil.getClientId());

    default Map&lt;String, Object&gt; clientInfo() {
        return clientDetails().getAdditionalInformation();

    default String tenant() {
        return (String) clientInfo().get(TENANT_NAME);


And then my actual class using the interface (and another interface that does similar things to add meta-information to the response):

public class Documents implements WrapAware, ClientAware {

        private DocumentService docService;

        @RequestMapping(method = RequestMethod.GET)
        public Object byPathAndTenant(@RequestParam("path") String path) {
            return ok(docService.getDocumentsByPathAndTenant(path, tenant()));


Note that it does resolve the beans appropriately and seems to work. Before I start utilizing a pattern like this I would like to be aware of the risks.