Spring 依赖注入与依赖查找来源的区别

2021-02-19

依赖查找的来源:

  • xml <bean>
  • BeanDefinitionRegistry#registerBeanDefinition
  • SingletonBeanRegistry#registerSingleton
  • 注解 @Bean
  • @Component 派生出的注解,如  @Configuration
  • IoC 容器内建 bean。如 ConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,EventListenerMethodProcessor,Environment,systemProperties — java.util.Properties,systemEnvironment — java.util.Map,MessageSource,LifecycleProcessor,ApplicationEventMulticaster

 

依赖注入的来源:

  • 依赖查找的来源
  • 外部化配置,如 @Value 注解获取的 properties 文件的属性值
  • ConfigurableListableBeanFactory#registerResolvableDependency

 

测试代码:

spring xml 配置

<bean name="user" class="constxiong.User"/>
<context:component-scan base-package="constxiong"/>
<context:property-placeholder location="classpath:META-INF/config.properties" />

 

config.properties

echo=\u4F60\u597D

 

User 类

package constxiong;

public class User {

    private Integer id;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
}

 

Bean 类

package constxiong;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

@Component
@Lazy
public class Bean {
	
	// xml <bean>
	@Resource(name="user")
	private User user;
	
	//BeanDefinitionRegistry#registerBeanDefinition
	@Resource(name="user1")
	private User user1;
	
	//SingletonBeanRegistry#registerSingleton
	@Resource(name="user2")
	private User user2;
	
	//注解 @Bean
	@Resource(name="user3")
	private User user3;
	
	//注解 @Configuration,@Component 派生出的注解
	@Autowired
	private Test test;
	
	//IoC 容器内建 bean
	@Autowired
	private ConfigurationClassPostProcessor configurationClassPostProcessor;
	
	//ConfigurableListableBeanFactory#registerResolvableDependency
	@Autowired(required=false)
	private String who;
	
	//外部化配置,config.properties 文件中的配置值
	@Value("${echo}")
	private String echo;

	public String toString() {
		return "Bean [user=" + user + ",\n user1=" + user1 + ",\n user2=" + user2
				+ ",\n user3=" + user3 + ",\n test=" + test
				+ ",\n configurationClassPostProcessor="
				+ configurationClassPostProcessor + ",\n who=" + who + ",\n echo="
				+ echo + "]";
	}
	
}

 

测试类

package constxiong;

import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 测试依赖查找、依赖注入来源的区别
 * 
 * @author ConstXiong
 */
@Configuration
public class Test {
	
	public static void main(String[] args) {
		System.out.println("依赖查找");
		lookup();//依赖查找
		System.out.println();
		System.out.println("依赖注入");
		inject();//依赖注入
	}

	/**
	 * 依赖查找的来源
	 */
	private static void lookup() {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring-lookup-inject-source.xml");
		
		((DefaultListableBeanFactory)context.getBeanFactory()).registerBeanDefinition("user1", 
				BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition());
		
		context.getBeanFactory().registerSingleton("user2", new User());
		
		// xml <bean>
		User user = context.getBean("user", User.class);
		System.out.println(user);
		
		//BeanDefinitionRegistry#registerBeanDefinition
		User user1 = context.getBean("user1", User.class);
		System.out.println(user1);
		
		//SingletonBeanRegistry#registerSingleton
		User user2 = context.getBean("user2", User.class);
		System.out.println(user2);
		
		//注解 @Bean
		User user3 = context.getBean("user3", User.class);
		System.out.println(user3);
		
		//注解 @Configuration,@Component 派生出的注解
		Test test = context.getBean("test", Test.class);
		System.out.println(test);
		
		//IoC 容器内建 bean
		//ConfigurationClassPostProcessor
		//AutowiredAnnotationBeanPostProcessor
		//CommonAnnotationBeanPostProcessor
		//EventListenerMethodProcessor
		//Environment
		//systemProperties — java.util.Properties
		//systemEnvironment — java.util.Map
		//MessageSource
		//LifecycleProcessor
		//ApplicationEventMulticaster
		ConfigurationClassPostProcessor innerBean = context.getBean(ConfigurationClassPostProcessor.class);
		System.out.println(innerBean);
		
	}
	
	@Bean
	public static User user3() {
		return new User();
	}
	
	/**
	 * 依赖注入的来源
	 */
	private static void inject() {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring-lookup-inject-source.xml");
		context.addBeanFactoryPostProcessor(beanFactory -> {
			beanFactory.registerResolvableDependency(String.class, "constxiong");
		});
		context.refresh();
		((DefaultListableBeanFactory)context.getBeanFactory()).registerBeanDefinition("user1", 
				BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition());
		
		context.getBeanFactory().registerSingleton("user2", new User());
		constxiong.Bean bean = context.getBean("bean", constxiong.Bean.class);
		System.out.println(bean);
	}

}

 

打印结果

ConstXiong 备案号:苏ICP备16009629号-3