Spring Autowired null if not found

nowszy94

Default @Autowired Spring implementation throws error when bean that should be autowired is not defined. Is it possible to configure Spring, that will assign null to object instead of throwing exception?

EDIT:

I've add required=false to Autowired but it still not working properly. Thats my code:

@Autowired
private ApplicationContext applicationContext;

@Autowired(required = false)
private HelloService helloService;

public HelloController() {
    message = "Hello World";
    System.out.println("Controller constructor");
}

@RequestMapping(method = RequestMethod.GET)
public ModelAndView helloWorld() {
    ModelAndView modelAndView = new ModelAndView("hello");
    if (helloService == null) {
        System.out.println(message);
    } else {
        helloService.hello();
        BeanDefinitionRegistry factory = (BeanDefinitionRegistry) applicationContext.getAutowireCapableBeanFactory();
        factory.removeBeanDefinition("helloService");
    }
    return modelAndView;
}

In first request it's autowired, but in next request after removing bean with factory.removeBeanDefinition("helloService"), controller bean is construct again, and i get NoSuchBeanDefinitionException

EDIT2:

I've created another controller with the following body:

@Autowired(required = false)
private TestService testService;

@RequestMapping(method = RequestMethod.GET)
public ModelAndView hello() {
    ModelAndView modelAndView = new ModelAndView("hello");
    return modelAndView;
}

and it works properly - Object is null and it doesn't get error. Maybe i should use different method to remove bean from Spring context?

Stacktrace:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'helloService' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:698) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1175) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.resolvedCachedArgument(AutowiredAnnotationBeanPostProcessor.java:508) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.access$200(AutowiredAnnotationBeanPostProcessor.java:115) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:538) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
...

STEPS TO REPRODUCE:

https://github.com/nowszy94/Autowired-null

Nikita Bakaev

The problem is that AutowiredAnnotationBeanPostProcessor cache injection result. So, when you delete bean from context, this class think that this object is actually exists(see private class AutowiredFieldElement extends InjectionMetadata.InjectedElement in AutowiredAnnotationBeanPostProcessor.class and method inject).So, you should clear that cache.

The most stupid way, that i found is, but looks like that you want to do

@Controller
@RequestMapping("/hello")
public class HelloController {

    @Autowired(required = false)
    private HelloService helloService;

    @Autowired
    private ApplicationContext applicationContext;

    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView modelAndView() {
        ModelAndView modelAndView = new ModelAndView("hello");
        if (helloService != null) {
            helloService.hello();
            removeBean("helloService");
        }

        return modelAndView;
    }

    private void removeBean(String beanName) {
        BeanDefinitionRegistry factory = (BeanDefinitionRegistry) applicationContext
                .getAutowireCapableBeanFactory();
        factory.removeBeanDefinition(beanName);
        clearCache(factory);
    }

    private void clearCache(BeanDefinitionRegistry beanFactory){
        AutowiredAnnotationBeanPostProcessor processor = null;

        for (BeanPostProcessor beanPostProcessor : ((DefaultListableBeanFactory) beanFactory).getBeanPostProcessors()){
            if (beanPostProcessor.getClass().equals(AutowiredAnnotationBeanPostProcessor.class)){
                processor = (AutowiredAnnotationBeanPostProcessor) beanPostProcessor;
            }
        }

        try {
            Field injectionMetadataCache = processor.getClass().getDeclaredField("injectionMetadataCache");
            injectionMetadataCache.setAccessible(true);
            Method clear = Map.class.getMethod("clear");
            clear.invoke( injectionMetadataCache.get(processor));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }


    }

}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Spring Boot Autowired null

From Dev

Spring @Autowired comes as null

From Dev

Spring - autowired fields are null

From Dev

Spring @Autowired field is null?

From Dev

Spring - autowired fields are null

From Dev

Spring autowired is null

From Dev

Autowired is null and not working with Jersey + Spring

From Dev

Spring MVC Autowired null in Component

From Dev

Spring @Autowired(required = true) is null

From Dev

Jersey 2 + Spring: @Autowired is null

From Dev

Spring Boot Autowired Repository null

From Dev

Spring @Autowired not working and returning null

From Dev

Spring @Autowired(required = true) is null

From Dev

spring @Autowired a repository returns null

From Dev

Spring @Autowired bean giving null

From Dev

Spring @Autowired bean not found, No qualifying bean of type [...] found

From Dev

FindBugs null issue with Spring @Autowired in Eclipse

From Dev

Spring @Autowired variable is null inside of @Component

From Java

Why is my Spring @Autowired field null?

From Dev

Spring DI - Autowired property is null in a REST service

From Dev

Spring autowired bean causes null pointer

From Dev

Spring @Autowired bean not initialising; Null Pointer Exception

From Dev

Autowired property is null - Spring Boot Configuration

From Dev

Spring Boot JavaConfig with Autowired dependencies that are null

From Dev

Autowired in CustomInterceptor getting null(Spring Boot)

From Dev

Spring bean is created, but is null when Autowired

From Dev

Why is my Spring @Autowired field returns null?

From Dev

Autowired property is null - Spring Boot Configuration

From Dev

Spring @Autowired gives null in a @Repository bean

Related Related

HotTag

Archive