代码示例:
@Component
public class OrderService {
}
public class UserService {
private OrderService orderServiceWithUser;
public void test(){
System.out.println(orderServiceWithUser);
}
public void setOrderService(OrderService orderService) {
this.orderServiceWithUser = orderService;
}
@ComponentScan("com.cms")
public class AppConfig {
@Bean(autowire = Autowire.BY_NAME)
public UserService userService () {
return new UserService();
}
}
public class Test {
public static void main(String[] args) {
// 创建一个Spring容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService) applicationContext.getBean("userService");
userService.test();
}
}
源码:
/* '自动注入'核心代码 。
自动注入只有两种形式:@Bean(autowire = Autowire.BY_NAME)、@Bean(autowire = Autowire.BY_TYPE);
如果只有@Bean,则是NO模型,下面的代码不会走。
*
* */
// 下面这段代码没有进行属性赋值,而是往pvs里面添加东西
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
// MutablePropertyValues是PropertyValues具体的实现类
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
Set<String> result = new TreeSet<>();
PropertyValues pvs = mbd.getPropertyValues();
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
// 什么样的属性能进行自动注入?
// 1.该属性有对应的set方法(只对set方法进行依赖注入)
// 2.没有在ignoredDependencyTypes中
// 3.如果该属性对应的set方法是实现的某个接口中所定义的,那么接口没有在ignoredDependencyInterfaces中
// 4.属性类型不是简单类型,比如int、Integer、int[]
for (PropertyDescriptor pd : pds) {
if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
// 属性如果是简单类型则不会依赖注入。
!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
result.add(pd.getName());
}
}
return StringUtils.toStringArray(result);
}
自动注入流程:
1、我们演示通过自动注入-byName的方式进行 属性依赖注入;这个name指的是UserService中set方法后面的名称,也就是setOrderService方法set后面的orderService;
2、通过@Bean(autowire = Autowire.BY_NAME/BY_TYPE)的自动注入方式在真正进行属性依赖注入前,会调用unsatisfiedNonSimpleProperties方法进行过滤(如果是简单类型,则不会注入。但是如果是通过@Autowired注解的方式却是可以的,因为它底层没有对简单类型进行过滤);
2、无论是byName还是byType都会用到setOrderService(OrderService orderService)。如果是byName则spring到IOC容器中找name=orderService的bean
(setOrderService方法中set后面的字符串名字),如果是byType则spring到IOC容器中找type=OrderService.class(setOrderService方法的参数)。如果找到则把OrderService对象赋值给setOrderService(OrderService orderService)方法的属性参数orderService;我们上面定义的setOrderService方法是把OrderService对象赋值给UserService中的orderServiceWithUser属性。
源码调试:
1、我们演示的是**自动注入-byName方式**
示例;
2、类中的每一个以set、get开头的方法都会封装成一个PropertyDescriptor对象
。PropertyDescriptor对象是把类中以set、get开头的方法作为一个’属性描述对象‘;比如UserService中set方法会被PropertyDescriptor中的writeMethod记录;UserService的get方法会被PropertyDescriptor中的readMethod记录。
3、每个类默认都有getClass()方法
。
如上图中pds中存储两个元素(代表UserService中存在两个’属性‘):一个是name=class(readMethod),一个是name=orderService(writeMethod)。你可能奇怪,UserService中明明只有一个setOrderService方法,为什么还会出现getClass方法呢?因为每个类都有一个默认存在的方法:this.getClass()。
4、通过@Bean(autowire = Autowire.BY_NAME/BY_TYPE)的自动注入的方式不会把简单类型进行依赖注入
。但是如果是通过@Autowired注解的方式却是可以的,因为它底层没有对简单类型进行过滤。简单类型如下:
public static boolean isSimpleProperty(Class<?> type) {
Assert.notNull(type, "'type' must not be null");
// 简单类型 || 存储简单类型的数组
return isSimpleValueType(type) || (type.isArray() && isSimpleValueType(type.getComponentType()));
}
-------------------
public static boolean isSimpleValueType(Class<?> type) {
return (Void.class != type && void.class != type &&
(ClassUtils.isPrimitiveOrWrapper(type) ||
Enum.class.isAssignableFrom(type) ||
CharSequence.class.isAssignableFrom(type) ||
Number.class.isAssignableFrom(type) ||
Date.class.isAssignableFrom(type) ||
Temporal.class.isAssignableFrom(type) ||
URI.class == type ||
URL.class == type ||
Locale.class == type ||
Class.class == type));
}
@ComponentScan("com.cms")
public class AppConfig {
@Bean
public Number number () {
return 1;
}
@Bean(autowire = Autowire.BY_NAME)
public UserService userService () {
return new UserService();
}
}
public class UserService {
private Number orderServiceWithUser;
public void test(){
System.out.println(orderServiceWithUser);
}
public void setOrderService(Number orderService) {
this.orderServiceWithUser = orderService;
}
}
@ComponentScan("com.cms")
public class AppConfig {
@Bean
public Number number () {
return 1;
}
@Bean(autowire = Autowire.BY_NAME)
public UserService userService () {
return new UserService();
}
}
public class UserService {
private Number orderServiceWithUser;
public void test(){
System.out.println(orderServiceWithUser);
}
public void setOrderService(Number orderService) {
this.orderServiceWithUser = orderService;
}
}
运行test方法之后,结果为:1。
源码位置:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean