12

Is there some way to make @Resource optional? This means if I don't have a bean of type requested by @Resource, I won't get Exception, but it would be just set to null.

MrProper
  • 1,500
  • 5
  • 19
  • 25
  • see here http://stackoverflow.com/questions/3957430/optional-spring-bean-references.It might helpful to you – PSR May 15 '13 at 08:31
  • ok looks like it isn't possible. Had to use @Autowired(required = false). Not what I exactly wanted, but it will do – MrProper May 15 '13 at 08:38

3 Answers3

9

ok looks like it isn't possible. Had to use @Autowired(required = false). Not what I exactly wanted, but it will do.

MrProper
  • 1,500
  • 5
  • 19
  • 25
  • It makes the resource optional, so it is what you want to do, even if you don't know this :) – Danubian Sailor May 15 '13 at 08:42
  • 1
    Autowired and Resource are two different things, try to inject with Autowired - it will work only for beans but not for resources – Maciej Miklas Nov 28 '13 at 14:00
  • @DanubianSailor — `@Autowired` is a Spring annotation, whereas `@Resource` is a common Java annotation. If you're not using Spring, then `@Autowired` wouldn't even be an option. – M. Justin May 19 '16 at 22:24
2

You can use @Value and default value (#{null}) on Resource type.

@Value("some-data.txt:#{null}") Resource resource

If file some-data.txt does not exist property isn't set as null but a resource with a non-existing file. You can call resource.exists() instead of resource != null.

public ResourceExample(@Value("some-data.txt:#{null}") Resource resource) {
    if (resource.exists()) {
        something(resource.getFile());
    }
}
radeklos
  • 2,168
  • 21
  • 19
1

You should be able to use a custom factory bean to achieve this:

public class OptionalFactoryBean<T> implements BeanFactoryAware, FactoryBean<T> {

    private String beanName;

    public void setBeanName(String beanName) {
         this.beanName = beanName;
    }

    @Override
    public T getObject() throws Exception {
        T result;
        try {
            result = beanFactory.getBean(beanName);
        } catch (NoSuchBeanDefinitionException ex) {
            result = null;
        }
        return result;
    }

    private BeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    private Class<?> objectType = Object.class;

    public void setObjectType(Class<?> objectType) {
        this.objectType = objectType != null? objectType : Object.class;
    }

    @Override
    public Class<?> getObjectType() {
        return objectType;
    }

    @Override
    public boolean isSingleton() {
         return true;
    }    
}

Spring configuration for your optional bean would be:

<bean id="myBean" class="mypackage.OptionalFactoryBean" scope="singleton">
    <property name="beanName" value="myRealBean"/>
    <property name="objectType" value="mypackage.MyRealBean"/>
</bean>

And you would get null injected. Then you could define:

<bean id="myRealBean" class="mypackage.MyRealBean" ...>
    <!-- .... -->
</bean>

if you wanted to inject some particular bean.

gpeche
  • 21,974
  • 5
  • 38
  • 51