依赖查找的来源:
- 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学习资源】整理推荐
- 自定义 Bean 作用域
- Bean 的作用域
- maven 集成 tomcat 以 jar 的方式打包 web 应用
- Spring 依赖注入与依赖查找来源的区别
- Spring 依赖注入的处理过程与 DependencyDescriptor 的说明
- Spring 各种 Aware 接口回调注入
- Spring Bean 生命周期内的 Exception 复现
- Spring 内建 Bean
- Spring Bean 的别名
- Spring Bean 未指定名称的命名规则
- Bean 何时被 GC
- Spring Bean 延迟加载
- ObjectFactory 与 BeanFactory 的区别
- Bean 销毁的方式与顺序
- Bean 初始化的方式与顺序
- Bean 的实例化方式
- Bean的注册方式
- 什么是 BeanDefinition?
- Spring IoC 容器启动时做了什么?
- BeanFactory 与 FactoryBean 的区别
- BeanFactory 与 ApplicationContext 的区别
- Spring IoC 依赖注入的实现方式
- Spring IoC 依赖注入(支持哪些数据类型?)
- Spring bean 依赖查找
- Spring-IoC
- Spring 的核心特性