get bean in spring context

In a web application using spring technology, there are two ways to obtain the Spring context ApplicationContext in the program:

1: Implement the ApplicationContextAware interface (implement the setApplicationContext method of this interface). In a web application, spring will load the springContext context at startup. The configuration file of spring configures <context:component-scan/> to scan and configure the @Component annotation The class, when the class that implements the ApplicationContextAware interface is scanned, the spring boot thread will automatically call the setApplicationContext method in this class, so that the spring context can be injected into the member variable in this class (assuming the name of this variable is applicationContext ).

When using the main method to test this class, you can use the constructor of ClassPathXmlApplicationContext to load the spring context, and then let the spring startup thread go through the above process. The loading order of web.xml is context-param->Listener (usually the Listener interface of spring configured here is ContextLoaderListener)->filter->servlet (springmvc is loaded as the first servlet), first load the ServletContext in tomcat, and then load The spring context, and then load the springmvc context. Spring's loading configuration file mechanism: configure listen-class: org.springframework.web.context.ContextLoaderListener in web.xml, this class is the entry of spring container, this interface has contextInitialized method (initialize root web application context) and contextDestroyed Method (destroy the root web application context). Break the point in the initWebApplicationContext method of the ContextLoader when the project starts. The context in the servletContext object at this time is org.apache.catalina.core.ApplicationContext, and the WebappClassLoader is used to continue. Load the XmlWebApplicationContext context, continue to the BeanUtils.instantiateClass method and use clazz.getDeclaredConstructor() to get a default constructor, skip the following process.

@Component
public class SpringContextHolder implements ApplicationContextAware {
	
	private static ApplicationContext applicationContext;

	private volatile static int i = 0 ;

	// Implement the context injection function of the ApplicationContextAware interface and store it in a static variable.
	public synchronized void setApplicationContext(ApplicationContext applicationContext) {
		System.out.println("i : " + (++i));
		SpringContextHolder.applicationContext = applicationContext;
	}

	// Get the ApplicationContext stored in a static variable.
	public static ApplicationContext getApplicationContext() {
		checkApplicationContext ();
		return applicationContext;
	}

	// Get the Bean from the static variable ApplicationContext and automatically convert it to the type of the assigned object.
	@SuppressWarnings("unchecked")
	public static <T> T getBean(String name) {
		checkApplicationContext ();
		return (T) applicationContext.getBean(name);

	}

	public static Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) {
		checkApplicationContext ();
		return applicationContext.getBeansWithAnnotation(annotationType);
	}

	// Get the Bean from the static variable ApplicationContext and automatically convert it to the type of the assigned object.
	// If there are multiple beans matching the Class, take the first one.
	@SuppressWarnings("unchecked")
	public static <T> T getBean(Class<T> clazz) {
		checkApplicationContext ();
		@SuppressWarnings("rawtypes")
		Map beanMaps = applicationContext.getBeansOfType(clazz);
		if (beanMaps != null && !beanMaps.isEmpty()) {
			return (T) beanMaps.values().iterator().next();
		} else {
			return null;
		}
	}

	public static <T> Map<String, T> getBeanMap(Class<T> clazz) {
		checkApplicationContext ();
		return applicationContext.getBeansOfType(clazz);
	}

	private static void checkApplicationContext() {
		if (applicationContext == null) {
			throw new IllegalStateException("applicaitonContext is not injected, please define SpringContextHolder in applicationContext.xml");
		}
	}
	
	public static void main(String[] args) {
		applicationContext = new ClassPathXmlApplicationContext("cfg-spring/spring-application.xml");
		Map<String, Object> map = SpringContextHolder.getBeansWithAnnotation(InitService.class);
		Iterator<Map.Entry<String, Object>> iter = map.entrySet().iterator();
		while(iter.hasNext()){
			Entry<String, Object> next = iter.next();
			System.out.println(next.getKey() + " : " + next.getValue());
		}
	}

 2: Inherit ApplicationObjectSupport (use this.getApplicationContext() directly in the current class)

For example: Map<String, Object> map = this.getApplicationContext().getBeansWithAnnotation(InitService.class) Get the class of the corresponding annotation (InitService) value directly in the map

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326580074&siteId=291194637