Spring ApplicationContext

1. Общ преглед

В този урок ще разгледаме подробно интерфейса на Spring ApplicationConext .

2. Интерфейсът ApplicationContext

Една от основните характеристики на Spring структурата е IoC (Inversion of Control) контейнер. Контейнерът Spring IoC е отговорен за управлението на обектите на приложение. Той използва инжектиране на зависимост, за да постигне обръщане на контрола.

Интерфейсите BeanFactory и ApplicationContext представляват Spring IoC контейнера . Тук BeanFactory е основният интерфейс за достъп до контейнера Spring. Той осигурява основни функционалности за управление на зърната.

От друга страна, ApplicationContext е подинтерфейс на BeanFactory . Следователно той предлага всички функционалности на BeanFactory.

Освен това той предоставя повече специфични за предприятието функционалности . Важните характеристики на ApplicationContext са разрешаване на съобщения, поддържане на интернационализация, публикуване на събития и специфични контексти на ниво приложение . Ето защо го използваме като контейнер Spring по подразбиране.

3. Какво е пролетен боб?

Преди да се потопим по-дълбоко в контейнера ApplicationContext , важно е да знаем за Spring spring. През пролетта боб е обект, който контейнерът Spring създава, сглобява и управлява .

И така, трябва ли да конфигурираме всички обекти на нашето приложение като Spring фасул? Е, като най-добра практика, не бива да го правим.

Според документацията на Spring, като цяло, трябва да дефинираме компоненти за обекти на сервизния слой, обекти за достъп до данни (DAO), презентационни обекти, инфраструктурни обекти като Hibernate SessionFactories, JMS Queues и т.н.

Също така, обикновено не трябва да конфигурираме фино зърнести обектни домейни в контейнера. Обикновено отговорността на DAO и бизнес логиката е да създават и зареждат обект на домейн.

Така че, нека дефинираме прост Java клас, който ще използваме като Spring bean в този урок:

public class AccountService { @Autowired private AccountRepository accountRepository; // getters and setters }

4. Конфигуриране на боб в контейнера

Както знаем, основната работа на ApplicationContext е да управлява боб.

И така, приложението трябва да предостави конфигурацията на компонента на контейнера ApplicationContext . Следователно конфигурацията на Spring bean се състои от една или повече дефиниции на боб. Също така Spring поддържа различни начини за конфигуриране на боб.

4.1. Java-базирана конфигурация

Първо, ще започнем с Java-базирана конфигурация, тъй като тя е най-новият и най-предпочитаният начин за конфигуриране на bean. Предлага се от пролет 3.0 нататък.

Java конфигурацията обикновено използва @ Bean-анотирани методи в клас @Configuration . В @Bean анотацията на метод показва, че методът създава Пролет боб. Освен това клас, анотиран с @Configuration, показва, че съдържа конфигурации на Spring bean.

И така, нека сега създадем конфигурационен клас, за да дефинираме нашия AccountService клас като Spring bean:

@Configuration public class AccountConfig { @Bean public AccountService accountService() { return new AccountService(accountRepository()); } @Bean public AccountRepository accountRepository() { return new AccountRepository(); } }

4.2. Конфигурация въз основа на анотации

Spring 2.5 въведе базирана на анотации конфигурация като първата стъпка за активиране на конфигурациите на компоненти в Java.

При този подход първо активираме конфигурация, базирана на анотации, чрез XML конфигурация. След това използваме набор от пояснения за нашите Java класове, методи, конструктори или полета, за да конфигурираме компоненти. Някои примери за тези пояснения са @Component , @Controller , @Service , @Repository , @Autowired и @Qualifier .

По-специално, ние също използваме тези пояснения с Java-базирана конфигурация. Освен това Spring продължава да добавя повече възможности към тези пояснения с всяко издание.

И така, нека да видим прост пример за тази конфигурация.

Първо, ще създадем XML конфигурацията, user-bean-config.xml , за да активираме пояснения:

Тук етикетът за конфигуриране на анотации позволява съпоставяне въз основа на пояснения . Също така, тагът за сканиране на компоненти казва на Spring къде да търси коментирани класове.

Второ, ще създадем клас UserService и ще го дефинираме като Spring bean, като използваме анотацията @Component :

@Component public class UserService { // user service code }

И тогава ще напишем прост тестов случай, за да тестваме тази конфигурация:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext/user-bean-config.xml"); UserService userService = context.getBean(UserService.class); assertNotNull(userService);

4.3. XML-базирана конфигурация

И накрая, нека да разгледаме XML-базирана конфигурация. Това е традиционният начин за конфигуриране на боб през пролетта.

Очевидно при този подход правим всички картографирания на компоненти в XML конфигурационен файл .

И така, нека създадем XML конфигурационен файл, account-bean-config.xml , и дефинираме зърна за нашия клас AccountService :

5. Видове ApplicationContext

Spring предоставя различни видове контейнери ApplicationContext , подходящи за различни изисквания. Това са реализации на интерфейса ApplicationContext . И така, нека да разгледаме някои от често срещаните видове ApplicationContext .

5.1. AnnotationConfigApplicationContext

First, let's see the AnnotationConfigApplicationContext class, which was introduced in Spring 3.0. It can take classes annotated with @Configuration, @Component, and JSR-330 metadata as input.

So, let's see a simple example of using the AnnotationConfigApplicationContext container with our Java-based configuration:

ApplicationContext context = new AnnotationConfigApplicationContext(AccountConfig.class); AccountService accountService = context.getBean(AccountService.class);

5.2. AnnotationConfigWebApplicationContext

AnnotationConfigWebApplicationContextis a web-based variant of AnnotationConfigApplicationContext.

We may use this class when we configure Spring's ContextLoaderListener servlet listener or a Spring MVC DispatcherServlet, in a web.xml file.

Moreover, from Spring 3.0 onward, we can also configure this application context container programmatically. All we need to do is to implement the WebApplicationInitializer interface:

public class MyWebApplicationInitializer implements WebApplicationInitializer { public void onStartup(ServletContext container) throws ServletException { AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.register(AccountConfig.class); context.setServletContext(container); // servlet configuration } }

5.3. XmlWebApplicationContext

If we use the XML based configuration in a web application, we can use the XmlWebApplicationContext class.

As a matter of fact, configuring this container is like the AnnotationConfigWebApplicationContext class only, which means we can configure it in web.xml or implement the WebApplicationInitializer interface:

public class MyXmlWebApplicationInitializer implements WebApplicationInitializer { public void onStartup(ServletContext container) throws ServletException { XmlWebApplicationContext context = new XmlWebApplicationContext(); context.setConfigLocation("/WEB-INF/spring/applicationContext.xml"); context.setServletContext(container); // Servlet configuration } }

5.4. FileSystemXMLApplicationContext

We use the FileSystemXMLApplicationContext class to load an XML-based Spring configuration file from the file system or from URLs. This class is useful when we need to load the ApplicationContext programmatically. In general, test harnesses and standalone applications are some of the possible use cases for this.

For example, let's see how we can create this Spring container and load the beans for our XML-based configuration:

String path = "C:/myProject/src/main/resources/applicationcontext/account-bean-config.xml"; ApplicationContext context = new FileSystemXmlApplicationContext(path); AccountService accountService = context.getBean("accountService", AccountService.class);

5.5. ClassPathXmlApplicationContext

In case we want to load an XML configuration file from the classpath, we can use the ClassPathXmlApplicationContext class. Similar to FileSystemXMLApplicationContext, it's useful for test harnesses as well as for application contexts embedded within JARs.

So, let's see an example of using this class:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext/account-bean-config.xml"); AccountService accountService = context.getBean("accountService", AccountService.class);

6. Additional Features of ApplicationContext

6.1. Message Resolution

The ApplicationContext interface supports message resolution and internationalization by extending the MessageSource interface. Furthermore, Spring provides two MessageSource implementations, ResourceBundleMessageSource and StaticMessageSource.

We can use the StaticMessageSource to programmatically add messages to the source. However, it supports basic internationalization and is more suitable for tests than production use.

On the other hand, ResourceBundleMessageSource is the most common implementation of MessageSource. It relies on the underlying JDK's ResouceBundle implementation. It also uses the JDK's standard message parsing provided by MessageFormat.

Now, let's see how can we use the MessageSource to read the messages from a properties file.

First, we'll create the messages.properties file on the classpath:

account.name=TestAccount

Second, we'll add a bean definition in our AccountConfig class:

@Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("config/messages"); return messageSource; }

Third, we'll inject the MessageSource in the AccountService:

@Autowired private MessageSource messageSource;

Finally, we can use the getMessage method anywhere in the AccountService to read the message:

messageSource.getMessage("account.name", null, Locale.ENGLISH);

Spring also provides the ReloadableResourceBundleMessageSource class, which allows for reading files from any Spring resource location and supports hot reloading of bundle property files.

6.2. Event Handling

ApplicationContext supports event handling with the help of the ApplicationEvent class and the ApplicationListener interface. It supports built-in events like ContextStartedEvent, ContextStoppedEvent, ContextClosedEvent, and RequestHandledEvent. Moreover, it also supports custom events for business use cases.

7. Conclusion

In this tutorial, we've discussed various aspects of the ApplicationContext container in Spring. We've seen different examples of how to configure Spring beans in an AppicationContext. Also, we've seen how to create and use different types of ApplicationContext.

Както винаги, пълният код е достъпен в GitHub.