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

依赖查找的来源:

  • 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=你好

 

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 + ",
 user1=" + user1 + ",
 user2=" + user2
				+ ",
 user3=" + user3 + ",
 test=" + test
				+ ",
 configurationClassPostProcessor="
				+ configurationClassPostProcessor + ",
 who=" + who + ",
 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.User@3bcd05cb
constxiong.User@3b6d844d
constxiong.User@36804139
constxiong.User@20bd8be5
constxiong.Test$$EnhancerBySpringCGLIB$$d5eb59ff@730d2164
org.springframework.context.annotation.ConfigurationClassPostProcessor@7068e664

依赖注入
Bean [user=constxiong.User@46b61c56,
 user1=constxiong.User@2e48362c,
 user2=constxiong.User@1efe439d,
 user3=constxiong.User@be68757,
 test=constxiong.Test$$EnhancerBySpringCGLIB$$d5eb59ff@7d446ed1,
 configurationClassPostProcessor=org.springframework.context.annotation.ConfigurationClassPostProcessor@12d2ce03,
 who=constxiong,
 echo=你好]

 

完整代码:020-spring-lookup-inject-source

 


【Java学习资源】整理推荐

 

 


【Java面试题与答案】整理推荐

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值