Spring (18) - define beans in the form of Java classes (2)

18.2 @Configuration

@Configuration is annotated on Class. When we need to configure Spring based on Java classes, we need to use @Configuration to annotate the corresponding configuration class, so that Spring will treat the corresponding Class as a configuration Class used. Configuration classes annotated with @Configuration are also registered by Spring as a bean by default. So when we have multiple configuration classes annotated with @Configuration, if the corresponding dependencies are in different @Configuration configuration classes when dependency injection is required, we can also inject the @Configuration configuration class, and then configure the injected @Configuration The corresponding method of the class instance produces an instance of the target dependent bean for injection. In the following example, we have two Java configuration classes, in which UserService in ServiceConfig needs to inject a UserDao defined in DaoConfig, then we inject a DaoConfig in ServiceConfig, and then obtain the corresponding UserDao by calling the userDao() method of DaoConfig Instance injected into the instance of UserService.

@Configuration
public class ServiceConfig {
	
	@Autowired
	private DaoConfig daoConfig;

	@Bean
	public UserService userService() {
		UserService userService = new UserServiceImpl(daoConfig.userDao());
		return userService;
	}
	
}

@Configuration
public class DaoConfig {

	@Bean
	public UserDao userDao() {
		UserDao userDao = new UserDaoImpl();
		return userDao;
	}
	
}

18.2.1 Scanning the classpath to register beans

Java class-based Spring configuration can also have Spring scan the classpath to register classes annotated with @Component annotations as bean definitions in the bean container, just like XML-based configuration. This is defined by annotating with @ComponentScan on the configuration.

@Configuration
@ComponentScan(basePackages="com.app")
public class SpringConfig {

}

In the above code, we use @ComponentScan to define that all classes marked with annotations such as @Component under the com.app package and its descendant packages in the classpath will be scanned, and they will be registered as a bean definition in the current bean container. It is equivalent to the following XML definition.

<context:component-scan base-package="com.app"/>

The filters that need to be used during scanning can be specified through the includeFilters and excludeFilters properties of @ComponentScan. The corresponding filter is specified through @Filter, and the type of filter can be specified through its type attribute. The default is ANNOTATION. The following example indicates that the @Service annotation will be excluded.

@Configuration
@ComponentScan(basePackages = "com.app", excludeFilters={@Filter(Service.class)})
public class ControllerConfig {

}

Basically use <context:component-scan/>the content that can be defined, @ComponentScan has corresponding properties to define, for more information, please refer to the related information of ComponentScan in the Spring API documentation.

18.3 Instantiating the bean container

18.3.1 Non-Web Environments

For bean container instantiation in non-Web environment, Spring provides us with a corresponding ApplicationContext implementation class - AnnotationConfigApplicationContext. When instantiating AnnotationConfigApplicationContext, we can directly pass in the Java configuration class as a construction parameter.

	public static void main(String args[]) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
		context.close();
	}

When there are multiple Java configuration classes, we can pass multiple Java configuration classes to AnnotationConfigApplicationContext.

	public static void main(String args[]) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
				SpringConfig.class, ServiceConfig.class, DaoConfig.class);
		context.close();
	}

We can also construct an empty AnnotationConfigApplicationContext first, and then register the Java class for configuration through the corresponding register() method.

	public static void main(String args[]) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context . register( SpringConfig . class); // Register a single configuration class 
		context . register( ServiceConfig . class, DaoConfig . class); // Register multiple configuration classes 
		context . refresh(); // Be sure to refresh( after registration ) once 
		context.close () ;
	}

In addition, it should be noted that AnnotationConfigApplicationContext not only receives classes annotated with @Configuration as configuration classes, but can also receive classes annotated with annotations such as @Component for bean annotations as configuration classes. Therefore, when we use AnnotationConfigApplicationContext directly, we can choose to use @Configuration to annotate the corresponding configuration class, or we can choose to use @Component and other bean-defining annotations to annotate.
For more information on AnnotationConfigApplicationContext please refer to the Spring API documentation.

18.3.2 Web Environment

For the Web environment, Spring provides an implementation class corresponding to WebApplicationContext—AnnotationConfigWebApplicationContext for Java-based configuration. If we need to use the WebApplicationContext, we need to pass <context-param/>or <init-param/>specify in the web.xml file.

We know that when using Spring in the Web environment, we usually need to define the following Listener in the web.xml file. Spring will instantiate the WebApplicationContext through the Listener, and by default, an XmlWebApplicationContext based on XML configuration will be instantiated.

<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

If we want the WebApplicationContext instantiated by ContextLoaderListener to be an AnnotationConfigWebApplicationContext, then we can define the following parameters in web.xml, which will be used by ContextLoaderListener to instantiate the corresponding WebApplicationContext implementation class.

<context-param>
	<param-name>contextClass</param-name>
	<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>

We know that the ContextLoaderListener based on XML configuration takes the applicationContext.xml file in the WEB-INF directory as the corresponding configuration file by default, and we can configure the corresponding configuration through the parameter contextConfigLocation. Then when the WebApplicationContext we use is AnnotationConfigWebApplicationContext, the corresponding contextConfigLocation also needs to be changed to our Java configuration class, and it must be the full name, that is, include the corresponding package name, and multiple configuration classes are separated by commas or semicolons or spaces. open. So for Web applications using Spring, we should define the corresponding ContextLoaderListener as follows. In the following example, we specify the corresponding contextClass as AnnotationConfigWebApplicationContext through the contextClass parameter, and then specify three Java configuration classes through the contextConfigLocation parameter.

<context-param>
	<param-name>contextClass</param-name>
	<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>com.app.SpringConfig,com. app.ServiceConfig,com.app.DaoConfig</param-value>
</context-param>

<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

For using SpringMVC, if we use Java class-based configuration to configure the corresponding SpringMVC definition, we need to define the contextClass and contextConfigLocation that need to be used when defining the DispatcherServlet. In the following example, we specify that SpringMVC will use AnnotationConfigWebApplicationContext as the contextClass, and the corresponding Java configuration class is com.app.ControllerConfig.

<servlet>
	<servlet-name>spring</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
		<param-name>contextClass</param-name>
		<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
	</init-param>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>com.app.ControllerConfig</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>spring</servlet-name>
	<url-pattern>*.do</url-pattern>
</servlet-mapping>

18.3.3 Test Environment

For unit testing using Spring Test, we can directly specify the Java configuration class to be used through the classes attribute of @ContextConfiguration. In the following example, we specify that the three Java configuration classes SpringConfig, ServiceConfig and DaoConfig will be used to build the corresponding ApplicationContext.

 

@ContextConfiguration(classes={SpringConfig.class, ServiceConfig.class, DaoConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class ConfigurationTest {
	
	@Autowired
	private ApplicationContext context;
	
	@Test
	public void test() {
		context.getBean("hello", Hello.class);
	}

}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326306900&siteId=291194637