2

In the example below, is there a way to avoid doing a context.getBean()? All the other beans subsequently used by the testService get autowired. (It is a console application)

public class Test { 


        private static ITestService testService;

        private static ApplicationContext context;

           public static void main(String[] args) { 

            context = new ClassPathXmlApplicationContext(
                    new String[]{"/META-INF/spring/app-context.xml"});
            ITestService testService = context.getBean(ITestService.class); 

        }

}

I tried adding autowire annotation to ApplicationContext, but it didnt work. Besides how does it know where my app-context.xml is located if I autowire it?

Update: I found what I needed over here

Community
  • 1
  • 1
developer747
  • 15,419
  • 26
  • 93
  • 147
  • Application context is not regular bean. Actually this class contains all other bean definitions. And this class runs scaning off `@Autowired` annotation. So, if context was not created, who will scan? – Ken Bekov Feb 22 '16 at 01:47
  • 1
    Take a look at @RunWith( SpringJUnit4ClassRunner.class ) – Brian Feb 22 '16 at 01:59

3 Answers3

3

Right, you're missing out a few details here.

Below is a short explanation of how Spring works.

1- The application context is loaded somehow (we will get there soon). 2- After loaded, app context will initialize/create all beans defined. Here is when beans get injected as dependencies. After this Whenever you get a bean back from the app context, that bean is all initialized and ready to go with all the dependencies in place (considering everything went fine).

RE the first step, there are a few way to automate the Spring initialization. One way is what you are doing, explicitly instantiating one. Other way could be via a context listener in case you're in a web environment, or maybe with the @RunWith. (You can find more here)

In your case, I believe you are looking for using Spring in a (Unit?!?) test environment so you are looking for something like

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class MyTest {

    @Autowired
    private ApplicationContext applicationContext;

    // class body...
}

further details here

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#testing

kryger
  • 12,906
  • 8
  • 44
  • 65
Desorder
  • 1,549
  • 12
  • 16
0

You cannot call beans without initializing the application context first. Secondly in your case Test class should be bean itself to be managed by spring then to autowire ITestService. The purpose of Application context as a container is to manage the bean lifecycle so u need to initialize it first by ClassPathXmlApplicationContextand then it will initialize all beans declared by you in ur xml file. About avoiding the getBean method if you are using servlets for creating web app you can avoid getBean. If not you should handle it manually.

i3rd
  • 66
  • 8
0

I agree with what @Desorder has said. When I started working with @RunWith(SpringJUnit4ClassRunner.class) and @ContextConfiguration, I used to get my test cases working. But it took me some time to understand how these two are working internally and their default configurations.

If you would like to take some different approach and would like to try without @RunWith and @ContextConfiguration, take a look at the link - TUTORIAL: JUNIT @RULE. With this, you will be very clear which spring xml file locations are provided.

asg
  • 2,248
  • 3
  • 18
  • 26