Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Dependency Injection Autowiring Null [duplicate]

I was able to use RestTemplate and autowire it. However I want to move my rest template related part of code into another class as follows:

public class Bridge {

    private final String BASE_URL = "http://localhost:8080/u";

    @Autowired
    RestTemplate restTemplate;

    public void addW() {
       Map<String, String> x = new HashMap<String, String>();
       W c = restTemplate.getForObject(BASE_URL + "/device/yeni", W.class, x);
       System.out.println("Here!");
    }
}

And at another class I call it:

...
Bridge wb = new Bridge();
wb.addW();
...

I am new to Spring and Dependency Injection terms. My restTemplate variable is null and throws an exception. What can I do it how to solve it(I don't know is it related to I use new keyword)?

like image 882
kamaci Avatar asked Nov 11 '11 08:11

kamaci


People also ask

Why are my Autowired fields null?

If the application starts and your field appears to be null it is generally due to one of the following issues: Using @Autowired on a static field. Omitted @Autowired on a field. Instance of bean not visible to Spring.

What will happen if I make @autowired as false?

By default, the @Autowired annotation implies that the dependency is required. This means an exception will be thrown when a dependency is not resolved. You can override that default behavior using the (required=false) option with @Autowired .

Why Autowired field injection is not recommended?

The reasons why field injection is frowned upon are as follows: You cannot create immutable objects, as you can with constructor injection. Your classes have tight coupling with your DI container and cannot be used outside of it. Your classes cannot be instantiated (for example in unit tests) without reflection.

What is difference between @autowired and @resource in Spring?

@Autowired in combination with @Qualifier also autowires by name. The main difference is is that @Autowired is a spring annotation whereas @Resource is specified by the JSR-250. So the latter is part of normal java where as @Autowired is only available by spring.


2 Answers

Using Bridge wb = new Bridge() does not work with dependency injection. Your restTemplate is not injected, because wb in not managed by Spring.

You have to make your Bridge a Spring bean itself, e.g. by annotation:

@Service
public class Bridge {
    // ...
}

or by bean declaration:

<bean id="bridge" class="Bridge"/>
like image 73
jeha Avatar answered Oct 18 '22 17:10

jeha


Just to add further to Jeha's correct answer.

Currently, by doing

Bridge wb = new Bridge();

Means that, that object instance is not "Spring Managed" - I.e. Spring does not know anything about it. So how can it inject a dependency it knows nothing about.

So as Jeha said. Add the @Service annotation or specify it in your application context xml config file (Or if you are using Spring 3 you @Configuration object)

Then when the Spring context starts up, there will be a Singleton (default behavior) instance of the Bridge.class in the BeanFactory. Either inject that into your other Spring-Managed objects, or pull it out manually e.g.

Bridge wb = (Bridge) applicationContext.getBean("bridge"); // Name comes from the default of the class

Now it will have the dependencies wired in.

like image 6
James 'Cookie' Cook Avatar answered Oct 18 '22 19:10

James 'Cookie' Cook